diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index dc441dd280..061ba7653b 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -4123,6 +4123,19 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t return TSDB_CODE_SUCCESS; } +int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) { + tSqlExpr* left = tSqlExprClone(expr); + tSqlExpr* right = expr; + + left->tokenId = TK_LT; + right->tokenId = TK_GT; + + *rexpr = tSqlExprCreate(left, right, TK_OR); + + return TSDB_CODE_SUCCESS; +} + + static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, tSqlExpr** tsExpr) { const char* msg1 = "table query cannot use tags filter"; @@ -4221,7 +4234,14 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql *type |= TSQL_EXPR_JOIN; } } else { - ret = setNormalExprToCond(tsExpr, *pExpr, parentOptr); + tSqlExpr *rexpr = NULL; + if ((*pExpr)->tokenId == TK_NE) { + handleNeOptr(&rexpr, *pExpr); + } else { + rexpr = *pExpr; + } + + ret = setNormalExprToCond(tsExpr, rexpr, parentOptr); if (type) { *type |= TSQL_EXPR_TS; } @@ -4272,6 +4292,12 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql // do nothing // ret = setExprToCond(pCmd, &pCondExpr->pTagCond, // *pExpr, NULL, parentOptr); + tSqlExpr *rexpr = NULL; + if ((*pExpr)->tokenId == TK_NE && (pSchema->type != TSDB_DATA_TYPE_BINARY && pSchema->type != TSDB_DATA_TYPE_NCHAR && pSchema->type != TSDB_DATA_TYPE_BOOL)) { + handleNeOptr(&rexpr, *pExpr); + *pExpr = rexpr; + } + if (type) { *type |= TSQL_EXPR_TAG; } @@ -4286,7 +4312,14 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - ret = setNormalExprToCond(columnExpr, *pExpr, parentOptr); + tSqlExpr *rexpr = NULL; + if ((*pExpr)->tokenId == TK_NE && (pSchema->type != TSDB_DATA_TYPE_BINARY && pSchema->type != TSDB_DATA_TYPE_NCHAR && pSchema->type != TSDB_DATA_TYPE_BOOL)) { + handleNeOptr(&rexpr, *pExpr); + } else { + rexpr = *pExpr; + } + + ret = setNormalExprToCond(columnExpr, rexpr, parentOptr); *pExpr = NULL; // remove it from expr tree } @@ -4575,37 +4608,40 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ return TSDB_CODE_SUCCESS; } +static int32_t createTimeRangeExpr(tSqlExpr** pExpr, STimeWindow* win, uint32_t tokenId) { + *pExpr = calloc(1, sizeof(tSqlExpr)); + + (*pExpr)->type = SQL_NODE_VALUE; + (*pExpr)->tokenId = tokenId; + (*pExpr)->value.nType = TSDB_DATA_TYPE_VALUE_ARRAY; + (*pExpr)->value.nLen = 2; + (*pExpr)->value.arr = taosArrayInit(2, sizeof(int64_t)); -static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, STimeWindow* win) { + taosArrayPush((*pExpr)->value.arr, &win->skey); + taosArrayPush((*pExpr)->value.arr, &win->ekey); + + return TSDB_CODE_SUCCESS; +} + +static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) { const char* msg0 = "invalid timestamp or operator for timestamp"; int32_t code = 0; - STimeWindow win2 = {.skey = INT64_MIN, .ekey = INT64_MAX}; + STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX}; if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } if (!tSqlExprIsParentOfLeaf(pExpr)) { - if (pExpr->tokenId == TK_OR) { - code = getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft, win); + code = convertTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft); if (code) { return code; } - code = getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight, &win2); + code = convertTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight); if (code) { return code; } - - return mergeTimeRange(pCmd, win, &win2, TSDB_RELATION_OR); - } - - code = getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft, win); - if (code) { - return code; - } - - return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight, win); } else { SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -4617,11 +4653,13 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE tSqlExpr* pRight = pExpr->pRight; - if (getTimeRange(&win2, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) { + if (getTimeRange(&win, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } - return mergeTimeRange(pCmd, win, &win2, TSDB_RELATION_AND); + createTimeRangeExpr(&pExpr->pRight, &win, pRight->tokenId); + + tSqlExprDestroy(pRight); } return TSDB_CODE_SUCCESS; @@ -4950,6 +4988,42 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { return TSDB_CODE_SUCCESS; } +static int32_t getQueryTimeRange(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr) { + int32_t ret = TSDB_CODE_SUCCESS; + + if (*pExpr == NULL) { + return ret; + } + + //multiple tables's query time range mixed together + + tExprNode* p = NULL; + SFilterInfo *filter = NULL; + + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); + ret = exprTreeFromSqlExpr(pCmd, &p, *pExpr, pQueryInfo, colList, NULL); + if (ret != TSDB_CODE_SUCCESS) { + goto _ret; + } + + ret = filterInitFromTree(p, &filter); + if (ret != TSDB_CODE_SUCCESS) { + goto _ret; + } + + ret = filterGetTimeRange(filter, &pQueryInfo->window); + +_ret: + tExprTreeDestroy(p, NULL); + + if (ret) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), tstrerror(ret)); + } + + return ret; +} + + int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { if (pExpr == NULL) { @@ -5000,12 +5074,11 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq } // 2. get the query time range - STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX}; - if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow, &win)) != TSDB_CODE_SUCCESS) { + if ((ret = convertTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) { return ret; } - if ((ret = mergeTimeRange(&pSql->cmd, &pQueryInfo->window,&win, TSDB_RELATION_AND)) != TSDB_CODE_SUCCESS) { + if ((ret = getQueryTimeRange(&pSql->cmd, pQueryInfo, &condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) { return ret; } @@ -5024,14 +5097,6 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq goto PARSE_WHERE_EXIT; } -/* - if (taosArrayGetSize(pQueryInfo->pUpstream) > 0 ) { - if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pTimewindow, TK_AND)) != TSDB_CODE_SUCCESS) { - goto PARSE_WHERE_EXIT; - } - } -*/ - if ((ret = getColQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr.pColumnCond)) != TSDB_CODE_SUCCESS) { goto PARSE_WHERE_EXIT; } diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 285ebfcf31..4ba2b35f3e 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -118,7 +118,7 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) { } else if (pNode->nodeType == TSQL_NODE_VALUE) { tVariantDestroy(pNode->pVal); } else if (pNode->nodeType == TSQL_NODE_COL) { - free(pNode->pSchema); + tfree(pNode->pSchema); } free(pNode); @@ -435,7 +435,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { expr->_node.optr = TSDB_RELATION_IN; tVariant* pVal = exception_calloc(1, sizeof(tVariant)); right->pVal = pVal; - pVal->nType = TSDB_DATA_TYPE_ARRAY; + pVal->nType = TSDB_DATA_TYPE_POINTER_ARRAY; pVal->arr = taosArrayInit(2, POINTER_BYTES); const char* cond = tbnameCond + QUERY_COND_REL_PREFIX_IN_LEN; diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index ffbdbd1bbe..057697fab2 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -368,21 +368,21 @@ static void getStatics_nchr(const void *pData, int32_t numOfRow, int64_t *min, i } tDataTypeDescriptor tDataTypes[15] = { - {TSDB_DATA_TYPE_NULL, 6,1, "NOTYPE", NULL, NULL, NULL}, - {TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", tsCompressBool, tsDecompressBool, getStatics_bool}, - {TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", tsCompressTinyint, tsDecompressTinyint, getStatics_i8}, - {TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", tsCompressSmallint, tsDecompressSmallint, getStatics_i16}, - {TSDB_DATA_TYPE_INT, 3, INT_BYTES, "INT", tsCompressInt, tsDecompressInt, getStatics_i32}, - {TSDB_DATA_TYPE_BIGINT, 6, LONG_BYTES, "BIGINT", tsCompressBigint, tsDecompressBigint, getStatics_i64}, - {TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", tsCompressFloat, tsDecompressFloat, getStatics_f}, - {TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", tsCompressDouble, tsDecompressDouble, getStatics_d}, - {TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", tsCompressString, tsDecompressString, getStatics_bin}, - {TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", tsCompressTimestamp, tsDecompressTimestamp, getStatics_i64}, - {TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", tsCompressString, tsDecompressString, getStatics_nchr}, - {TSDB_DATA_TYPE_UTINYINT, 16, CHAR_BYTES, "TINYINT UNSIGNED", tsCompressTinyint, tsDecompressTinyint, getStatics_u8}, - {TSDB_DATA_TYPE_USMALLINT, 17, SHORT_BYTES, "SMALLINT UNSIGNED", tsCompressSmallint, tsDecompressSmallint, getStatics_u16}, - {TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", tsCompressInt, tsDecompressInt, getStatics_u32}, - {TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", tsCompressBigint, tsDecompressBigint, getStatics_u64}, + {TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE", 0, 0, NULL, NULL, NULL}, + {TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", false, true, tsCompressBool, tsDecompressBool, getStatics_bool}, + {TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", INT8_MIN, INT8_MAX, tsCompressTinyint, tsDecompressTinyint, getStatics_i8}, + {TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", INT16_MIN, INT16_MAX, tsCompressSmallint, tsDecompressSmallint, getStatics_i16}, + {TSDB_DATA_TYPE_INT, 3, INT_BYTES, "INT", INT32_MIN, INT32_MAX, tsCompressInt, tsDecompressInt, getStatics_i32}, + {TSDB_DATA_TYPE_BIGINT, 6, LONG_BYTES, "BIGINT", INT64_MIN, INT64_MAX, tsCompressBigint, tsDecompressBigint, getStatics_i64}, + {TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", 0, 0, tsCompressFloat, tsDecompressFloat, getStatics_f}, + {TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", 0, 0, tsCompressDouble, tsDecompressDouble, getStatics_d}, + {TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", 0, 0, tsCompressString, tsDecompressString, getStatics_bin}, + {TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", INT64_MIN, INT64_MAX, tsCompressTimestamp, tsDecompressTimestamp, getStatics_i64}, + {TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr}, + {TSDB_DATA_TYPE_UTINYINT, 16, CHAR_BYTES, "TINYINT UNSIGNED", 0, UINT8_MAX, tsCompressTinyint, tsDecompressTinyint, getStatics_u8}, + {TSDB_DATA_TYPE_USMALLINT, 17, SHORT_BYTES, "SMALLINT UNSIGNED", 0, UINT16_MAX, tsCompressSmallint, tsDecompressSmallint, getStatics_u16}, + {TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", 0, UINT32_MAX, tsCompressInt, tsDecompressInt, getStatics_u32}, + {TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", 0, UINT64_MAX, tsCompressBigint, tsDecompressBigint, getStatics_u64}, }; char tTokenTypeSwitcher[13] = { @@ -560,65 +560,50 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) { } } -int8_t getInt8Val(void *s) { - return (int8_t)GET_INT8_VAL(s); -} -uint8_t getUint8Val(void *s) { - return (uint8_t)GET_INT8_VAL(s); -} -int16_t getInt16Val(void *s) { - return (int16_t)GET_INT16_VAL(s); -} -uint16_t getUint16Val(void *s) { - return (uint16_t)GET_INT16_VAL(s); -} -int32_t getInt32Val(void *s) { - return (int32_t)GET_INT32_VAL(s); -} -uint32_t getUint32Val(void *s) { - return (uint32_t)GET_INT32_VAL(s); -} -int64_t getInt64Val(void *s) { - return (int64_t)GET_INT64_VAL(s); -} -uint64_t getUint64Val(void *s) { - return (uint64_t)GET_INT64_VAL(s); -} -float getFloatVal(void *s) { - return GET_FLOAT_VAL(s); -} -double getDoubleVal(void *s) { - return GET_DOUBLE_VAL(s); -} -void setInt8Val(void *d, void *s) { - *((int8_t *)d) = (int8_t)GET_INT8_VAL(s); -} -void setUint8Val(void *d, void *s) { - *((uint8_t *)d) = GET_INT8_VAL(s); -} -void setInt16Val(void *d, void *s) { - *((int16_t *)d) = (int16_t)GET_INT16_VAL(s); -} -void setUint16Val(void *d, void *s) { - *((uint16_t *)d) = GET_INT16_VAL(s); -} -void setInt32Val(void *d, void *s) { - *((int32_t *)d) = GET_INT32_VAL(s); -} -void setUint32Val(void *d, void *s) { - *((uint32_t *)d) = GET_INT32_VAL(s); -} -void setInt64Val(void *d, void *s) { - *((int64_t *)d) = GET_INT64_VAL(s); -} -void setUint64Val(void *d, void *s) { - *((uint64_t *)d) = GET_INT64_VAL(s); -} -void setFloatVal(void *d, void *s) { - SET_FLOAT_VAL(d, GET_FLOAT_VAL(s)); -} -void setDoubleVal(void *d, void *s) { - SET_DOUBLE_VAL(d, GET_DOUBLE_VAL(s)); +void operateVal(void *dst, void *s1, void *s2, int32_t optr, int32_t type) { + if (optr == TSDB_BINARY_OP_ADD) { + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + *((int8_t *)dst) = GET_INT8_VAL(s1) + GET_INT8_VAL(s2); + break; + case TSDB_DATA_TYPE_UTINYINT: + *((uint8_t *)dst) = GET_UINT8_VAL(s1) + GET_UINT8_VAL(s2); + break; + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t *)dst) = GET_INT16_VAL(s1) + GET_INT16_VAL(s2); + break; + case TSDB_DATA_TYPE_USMALLINT: + *((uint16_t *)dst) = GET_UINT16_VAL(s1) + GET_UINT16_VAL(s2); + break; + case TSDB_DATA_TYPE_INT: + *((int32_t *)dst) = GET_INT32_VAL(s1) + GET_INT32_VAL(s2); + break; + case TSDB_DATA_TYPE_UINT: + *((uint32_t *)dst) = GET_UINT32_VAL(s1) + GET_UINT32_VAL(s2); + break; + case TSDB_DATA_TYPE_BIGINT: + *((int64_t *)dst) = GET_INT64_VAL(s1) + GET_INT64_VAL(s2); + break; + case TSDB_DATA_TYPE_UBIGINT: + *((uint64_t *)dst) = GET_UINT64_VAL(s1) + GET_UINT64_VAL(s2); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + *((int64_t *)dst) = GET_INT64_VAL(s1) + GET_INT64_VAL(s2); + break; + case TSDB_DATA_TYPE_FLOAT: + SET_FLOAT_VAL(dst, GET_FLOAT_VAL(s1) + GET_FLOAT_VAL(s2)); + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_VAL(dst, GET_DOUBLE_VAL(s1) + GET_DOUBLE_VAL(s2)); + break; + default: { + assert(0); + break; + } + } + } else { + assert(0); + } } diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index 1168eeb231..1a5bbdf28c 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -184,7 +184,7 @@ void tVariantDestroy(tVariant *pVar) { } // NOTE: this is only for string array - if (pVar->nType == TSDB_DATA_TYPE_ARRAY) { + if (pVar->nType == TSDB_DATA_TYPE_POINTER_ARRAY) { size_t num = taosArrayGetSize(pVar->arr); for(size_t i = 0; i < num; i++) { void* p = taosArrayGetP(pVar->arr, i); @@ -192,6 +192,9 @@ void tVariantDestroy(tVariant *pVar) { } taosArrayDestroy(pVar->arr); pVar->arr = NULL; + } else if (pVar->nType == TSDB_DATA_TYPE_VALUE_ARRAY) { + taosArrayDestroy(pVar->arr); + pVar->arr = NULL; } } @@ -220,7 +223,7 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { if (IS_NUMERIC_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) { pDst->i64 = pSrc->i64; - } else if (pSrc->nType == TSDB_DATA_TYPE_ARRAY) { // this is only for string array + } else if (pSrc->nType == TSDB_DATA_TYPE_POINTER_ARRAY) { // this is only for string array size_t num = taosArrayGetSize(pSrc->arr); pDst->arr = taosArrayInit(num, sizeof(char*)); for(size_t i = 0; i < num; i++) { @@ -228,9 +231,18 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { char* n = strdup(p); taosArrayPush(pDst->arr, &n); } + } else if (pSrc->nType == TSDB_DATA_TYPE_VALUE_ARRAY) { + size_t num = taosArrayGetSize(pSrc->arr); + pDst->arr = taosArrayInit(num, sizeof(int64_t)); + pDst->nLen = pSrc->nLen; + assert(pSrc->nLen == num); + for(size_t i = 0; i < num; i++) { + int64_t *p = taosArrayGet(pSrc->arr, i); + taosArrayPush(pDst->arr, p); + } } - if (pDst->nType != TSDB_DATA_TYPE_ARRAY) { + if (pDst->nType != TSDB_DATA_TYPE_POINTER_ARRAY && pDst->nType != TSDB_DATA_TYPE_VALUE_ARRAY) { pDst->nLen = tDataTypes[pDst->nType].bytes; } } diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 431c9116cc..f73ae9e543 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -260,6 +260,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW TAOS_DEF_ERROR_CODE(0, 0x070A) //"Too many time window in query") #define TSDB_CODE_QRY_NOT_ENOUGH_BUFFER TAOS_DEF_ERROR_CODE(0, 0x070B) //"Query buffer limit has reached") #define TSDB_CODE_QRY_INCONSISTAN TAOS_DEF_ERROR_CODE(0, 0x070C) //"File inconsistency in replica") +#define TSDB_CODE_QRY_INVALID_TIME_CONDITION TAOS_DEF_ERROR_CODE(0, 0x070D) //"invalid time condition") // grant diff --git a/src/inc/ttype.h b/src/inc/ttype.h index 9949f31c59..fe19076252 100644 --- a/src/inc/ttype.h +++ b/src/inc/ttype.h @@ -29,7 +29,8 @@ typedef struct tstr { #define IS_VAR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_BINARY) || ((t) == TSDB_DATA_TYPE_NCHAR)) // this data type is internally used only in 'in' query to hold the values -#define TSDB_DATA_TYPE_ARRAY (1000) +#define TSDB_DATA_TYPE_POINTER_ARRAY (1000) +#define TSDB_DATA_TYPE_VALUE_ARRAY (1001) #define GET_TYPED_DATA(_v, _finalType, _type, _data) \ do { \ @@ -161,6 +162,8 @@ typedef struct tDataTypeDescriptor { int16_t nameLen; int32_t bytes; char * name; + int64_t minValue; + int64_t maxValue; int (*compFunc)(const char *const input, int inputSize, const int nelements, char *const output, int outputSize, char algorithm, char *const buffer, int bufferSize); int (*decompFunc)(const char *const input, int compressedSize, const int nelements, char *const output, @@ -180,6 +183,7 @@ void *getNullValue(int32_t type); void assignVal(char *val, const char *src, int32_t len, int32_t type); void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf); +void operateVal(void *dst, void *s1, void *s2, int32_t optr, int32_t type); int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bool issigned); diff --git a/src/query/inc/qFilter.h b/src/query/inc/qFilter.h index afa8423244..78c1c1d9db 100644 --- a/src/query/inc/qFilter.h +++ b/src/query/inc/qFilter.h @@ -41,30 +41,50 @@ enum { MR_OPT_TS = 1, }; +enum { + RA_EXCLUDE = 1, + RA_NULL = 2, +}; + typedef struct OptrStr { uint16_t optr; char *str; } OptrStr; +typedef struct SFilterColRange { + uint16_t idx; //column field idx + int64_t s; + int64_t e; +} SFilterColRange; + typedef struct SFilterRange { - struct SFilterRange* prev; - struct SFilterRange* next; + char sflag; + char eflag; int64_t s; int64_t e; } SFilterRange; + +typedef struct SFilterRangeNode { + struct SFilterRangeNode* prev; + struct SFilterRangeNode* next; + SFilterRange ra; +} SFilterRangeNode; + typedef struct SFilterRMCtx { int32_t type; int32_t options; int8_t status; __compar_fn_t pCompareFunc; - SFilterRange *rs; + SFilterRangeNode *rf; //freed + SFilterRangeNode *rs; } SFilterRMCtx ; typedef struct SFilterField { uint16_t type; void* desc; void* data; + int64_t range[]; } SFilterField; typedef struct SFilterFields { @@ -106,14 +126,23 @@ typedef struct SFilterInfo { uint8_t *unitFlags; // got result } SFilterInfo; +#define COL_FIELD_SIZE (sizeof(SFilterField) + 2 * sizeof(int64_t)) + +#define FILTER_NO_MERGE_DATA_TYPE(t) ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR) +#define FILTER_NO_MERGE_OPTR(o) ((o) == TSDB_RELATION_ISNULL || (o) == TSDB_RELATION_NOTNULL) + +#define MR_EMPTY_RES(ctx) (ctx->rs == NULL) + #define MR_GET_FLAG(st, f) (st & f) #define MR_SET_FLAG(st, f) st |= (f) -#define GEN_RANGE(r, t, s, e) do { r = calloc(1, sizeof(SFilterRange)); assignVal((char*)&(r)->s, s, 0, t); assignVal((char*)&(r)->e, e, 0, t); } while (0) -#define FREE_RANGE(rs, r) do { if (r->prev) { r->prev->next = r->next; } else { rs = r->next;} if (r->next) { r->next->prev = r->prev; } free(r); } while (0) -#define FREE_FROM_RANGE(rs, r) do { if (r->prev) { r->prev->next = NULL; } else { rs = NULL;} while (r) {SFilterRange *n = r->next; free(r); r = n; } } while (0) -#define INSERT_RANGE(rs, r, t, s, e) do { SFilterRange *n = calloc(1, sizeof(SFilterRange)); assignVal((char*)&n->s, s, 0, t); assignVal((char*)&n->e, e, 0, t); n->prev = r->prev; r->prev = n; if (r->prev) { r->prev->next = n; } else { rs->next = n; } n->next = r; } while (0) -#define APPEND_RANGE(r, t, s, e) do { SFilterRange *n = calloc(1, sizeof(SFilterRange)); assignVal((char*)&n->s, s, 0, t); assignVal((char*)&n->e, e, 0, t); n->prev = r; r->next = n; } while (0) +#define SIMPLE_COPY_VALUES(dst, src) *((int64_t *)dst) = *((int64_t *)src) + +#define RESET_RANGE(ctx, r) do { r->next = ctx->rf; ctx->rf = r; } while (0) +#define FREE_RANGE(ctx, r) do { if (r->prev) { r->prev->next = r->next; } else { ctx->rs = r->next;} if (r->next) { r->next->prev = r->prev; } RESET_RANGE(ctx, r); } while (0) +#define FREE_FROM_RANGE(ctx, r) do { if (r->prev) { r->prev->next = NULL; } else { ctx->rs = NULL;} while (r) {SFilterRangeNode *n = r->next; RESET_RANGE(ctx, r); r = n; } } while (0) +#define INSERT_RANGE(ctx, r, t, s, e) do { SFilterRangeNode *n = filterNewRange(ctx, t, s, e); n->prev = r->prev; if (r->prev) { r->prev->next = n; } else { ctx->rs = n; } r->prev = n; n->next = r; } while (0) +#define APPEND_RANGE(ctx, r, t, s, e) do { SFilterRangeNode *n = filterNewRange(ctx, t, s, e); n->prev = r; if (r) { r->next = n; } else { ctx->rs = n; } } while (0) #define ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { return _code; } } while (0) #define ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); return _code; } } while (0) @@ -121,6 +150,7 @@ typedef struct SFilterInfo { #define CHK_RETV(c) do { if (c) { return; } } while (0) #define CHK_RET(c, r) do { if (c) { return r; } } while (0) +#define CHK_JMP(c) do { if (c) { goto _err_return; } } while (0) #define CHK_LRETV(c,...) do { if (c) { qError(__VA_ARGS__); return; } } while (0) #define CHK_LRET(c, r,...) do { if (c) { qError(__VA_ARGS__); return r; } } while (0) @@ -130,7 +160,13 @@ typedef struct SFilterInfo { #define FILTER_GET_VAL_FIELD_TYPE(fi) (((tVariant *)((fi)->desc))->nType) #define FILTER_GET_VAL_FIELD_DATA(fi) ((fi)->data) - +#define FILTER_GROUP_UNIT(i, g, uid) ((i)->units[(g)->unitIdxs[uid]]) +#define FILTER_UNIT_LEFT_FIELD(i, u) FILTER_GET_FIELD(i, (u)->left) +#define FILTER_UNIT_RIGHT_FIELD(i, u) FILTER_GET_FIELD(i, (u)->right) +#define FILTER_UNIT_DATA_TYPE(i, u) FILTER_GET_COL_FIELD_TYPE(FILTER_UNIT_LEFT_FIELD(i, u)) +#define FILTER_UNIT_VAL(i, u) FILTER_GET_VAL_FIELD_DATA(FILTER_UNIT_RIGHT_FIELD(i, u)) +#define FILTER_UNIT_COL_IDX(u) ((u)->left.idx) +#define FILTER_UNIT_OPTR(u) ((u)->compare.optr) #define FILTER_UNIT_CLR_F(i) memset((i)->unitFlags, 0, (i)->unitNum * sizeof(*info->unitFlags)) #define FILTER_UNIT_SET_F(i, idx) (i)->unitFlags[idx] = 1 @@ -149,7 +185,7 @@ extern int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr); extern int32_t filterGetMergeRangeNum(void* h, int32_t* num); extern int32_t filterGetMergeRangeRes(void* h, void *s, void* e); extern int32_t filterFreeMergeRange(void* h); - +extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win); #ifdef __cplusplus } #endif diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index afc9eab0b0..63e5c50c50 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6966,7 +6966,10 @@ int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters) { return TSDB_CODE_QRY_APP_ERROR; } - return filterInitFromTree(expr, pFilters); + int32_t ret = filterInitFromTree(expr, pFilters); + tExprTreeDestroy(expr, NULL); + + return ret; } @@ -7284,10 +7287,6 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S } doUpdateExprColumnIndex(pQueryAttr); - int32_t ret = createFilterInfo(pQueryAttr, pQInfo->qId); - if (ret != TSDB_CODE_SUCCESS) { - goto _cleanup; - } if (pQueryAttr->fillType != TSDB_FILL_NONE) { pQueryAttr->fillVal = malloc(sizeof(int64_t) * pQueryAttr->numOfOutput); diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 06f85d4af1..56a53ebd50 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -54,6 +54,24 @@ filter_desc_compare_func gDescCompare [F_FIELD_MAX] = { filterFieldValDescCompare }; +static FORCE_INLINE SFilterRangeNode* filterNewRange(SFilterRMCtx *ctx, int32_t t, void *s, void *e) { + SFilterRangeNode *r = NULL; + + if (ctx->rf) { + r = ctx->rf; + ctx->rf = ctx->rf->next; + r->prev = NULL; + r->next = NULL; + } else { + r = calloc(1, sizeof(SFilterRangeNode)); + } + + SIMPLE_COPY_VALUES((char*)&r->s, s); + SIMPLE_COPY_VALUES((char*)&r->e, e); + + return r; +} + void* filterInitMergeRange(int32_t type, int32_t options) { if (type > TSDB_DATA_TYPE_UBIGINT || type < TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { qError("not supported range type:%d", type); @@ -63,46 +81,97 @@ void* filterInitMergeRange(int32_t type, int32_t options) { SFilterRMCtx *ctx = calloc(1, sizeof(SFilterRMCtx)); ctx->type = type; + ctx->options = options; ctx->pCompareFunc = getComparFunc(type, 0); return ctx; } -int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { +int32_t filterAddMergeRangeCtx(void *dst, void *src, int32_t optr) { + SFilterRMCtx *dctx = (SFilterRMCtx *)dst; + SFilterRMCtx *sctx = (SFilterRMCtx *)src; + + if (sctx->rs == NULL) { + return TSDB_CODE_SUCCESS; + } + + SFilterRangeNode *r = sctx->rs; + + while (r) { + filterAddMergeRange(dctx, &r->s, &r->e, optr); + r = r->next; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t filterResetMergeRangeCtx(SFilterRMCtx *ctx) { + ctx->status = 0; + + if (ctx->rf == NULL) { + ctx->rf = ctx->rs; + ctx->rs = NULL; + return TSDB_CODE_SUCCESS; + } + + SFilterRangeNode *r = ctx->rf; + + while (r && r->next) { + r = r->next; + } + + r->next = ctx->rs; + ctx->rs = NULL; + return TSDB_CODE_SUCCESS; +} + +int32_t filterReuseMergeRangeCtx(SFilterRMCtx *ctx, int32_t type, int32_t options) { + filterResetMergeRangeCtx(ctx); + + ctx->type = type; + ctx->options = options; + ctx->pCompareFunc = getComparFunc(type, 0); + + return TSDB_CODE_SUCCESS; +} + + + +int32_t filterAddMergeRangeImpl(void* h, void* s, void* e, char sflag, char eflag, int32_t optr) { SFilterRMCtx *ctx = (SFilterRMCtx *)h; if (ctx->rs == NULL) { if (MR_GET_FLAG(ctx->status, MR_ST_START) == 0 || optr == TSDB_RELATION_OR) { - GEN_RANGE(ctx->rs, ctx->type, s, e); + APPEND_RANGE(ctx, ctx->rs, ctx->type, s, e); MR_SET_FLAG(ctx->status, MR_ST_START); } return TSDB_CODE_SUCCESS; } - SFilterRange *r = ctx->rs; - SFilterRange *rn = NULL; + SFilterRangeNode *r = ctx->rs; + SFilterRangeNode *rn = NULL; if (optr == TSDB_RELATION_AND) { while (r != NULL) { if (ctx->pCompareFunc(&r->s, e) > 0) { - FREE_FROM_RANGE(ctx->rs, r); + FREE_FROM_RANGE(ctx, r); break; } if (ctx->pCompareFunc(s, &r->e) > 0) { rn = r->next; - FREE_RANGE(ctx->rs, r); + FREE_RANGE(ctx, r); r = rn; continue; } if (ctx->pCompareFunc(s, &r->s) > 0) { - assignVal((char *)&r->s, s, 0, ctx->type); + SIMPLE_COPY_VALUES((char *)&r->s, s); } if (ctx->pCompareFunc(&r->e, e) > 0) { - assignVal((char *)&r->e, e, 0, ctx->type); + SIMPLE_COPY_VALUES((char *)&r->e, e); break; } @@ -120,7 +189,7 @@ int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { while (r != NULL) { if (ctx->pCompareFunc(&r->s, e) > 0) { if (emerged == false) { - INSERT_RANGE(ctx->rs, r, ctx->type, s, e); + INSERT_RANGE(ctx, r, ctx->type, s, e); } break; @@ -132,13 +201,13 @@ int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { continue; } - APPEND_RANGE(r, ctx->type, s, e); + APPEND_RANGE(ctx, r, ctx->type, s, e); break; } if (smerged == false) { if (ctx->pCompareFunc(&r->s, s) > 0) { - assignVal((char *)&r->s, s, 0, ctx->type); + SIMPLE_COPY_VALUES((char *)&r->s, s); } smerged = true; @@ -146,7 +215,7 @@ int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { if (emerged == false) { if (ctx->pCompareFunc(e, &r->e) > 0) { - assignVal((char *)&r->e, e, 0, ctx->type); + SIMPLE_COPY_VALUES((char *)&r->e, e); emerged = true; e = &r->e; r = r->next; @@ -158,13 +227,13 @@ int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { if (ctx->pCompareFunc(e, &r->e) > 0) { rn = r->next; - FREE_RANGE(ctx->rs, r); + FREE_RANGE(ctx, r); r = rn; continue; } else { - assignVal(e, (char *)&r->e, 0, ctx->type); - FREE_RANGE(ctx->rs, r); + SIMPLE_COPY_VALUES(e, (char *)&r->e); + FREE_RANGE(ctx, r); break; } @@ -173,6 +242,29 @@ int32_t filterAddMergeRange(void* h, void* s, void* e, int32_t optr) { return TSDB_CODE_SUCCESS; } +int32_t filterAddMergeRange(void* h, SFilterRange* ra, int32_t optr) { + SFilterRMCtx *ctx = (SFilterRMCtx *)h; + int64_t sv, ev; + void *s, *e; + char sflag = 0, eflag = 0; + + if (MR_GET_FLAG(ra->sflag, RA_NULL)) { + SIMPLE_COPY_VALUES(&sv, &tDataTypes[ctx->type].minValue); + s = &sv; + } else { + s = &ra.s; + } + + if (MR_GET_FLAG(ra->eflag, RA_NULL)) { + SIMPLE_COPY_VALUES(&ev, &tDataTypes[ctx->type].maxValue); + e = &ev; + } else { + e = &ra.e; + } + + return filterAddMergeRangeImpl(h, s, e, ra.sflag, ra.eflag, optr); +} + int32_t filterFinMergeRange(void* h) { SFilterRMCtx *ctx = (SFilterRMCtx *)h; @@ -181,7 +273,23 @@ int32_t filterFinMergeRange(void* h) { } if (MR_GET_FLAG(ctx->options, MR_OPT_TS)) { - + SFilterRangeNode *r = ctx->rs; + SFilterRangeNode *rn = NULL; + + while (r && r->next) { + int64_t tmp = 1; + operateVal(&tmp, &r->e, &tmp, TSDB_BINARY_OP_ADD, ctx->type); + if (ctx->pCompareFunc(&tmp, &r->next->s) == 0) { + rn = r->next; + SIMPLE_COPY_VALUES((char *)&r->next->s, (char *)&r->s); + FREE_RANGE(ctx, r); + r = rn; + + continue; + } + + r = r->next; + } } MR_SET_FLAG(ctx->status, MR_ST_FIN); @@ -196,7 +304,7 @@ int32_t filterGetMergeRangeNum(void* h, int32_t* num) { *num = 0; - SFilterRange *r = ctx->rs; + SFilterRangeNode *r = ctx->rs; while (r) { ++(*num); @@ -212,7 +320,7 @@ int32_t filterGetMergeRangeRes(void* h, void *s, void* e) { SFilterRMCtx *ctx = (SFilterRMCtx *)h; uint32_t num = 0; - SFilterRange* r = ctx->rs; + SFilterRangeNode* r = ctx->rs; while (r) { assignVal(s + num * tDataTypes[ctx->type].bytes, (char *)&r->s, 0, ctx->type); @@ -231,9 +339,13 @@ int32_t filterGetMergeRangeRes(void* h, void *s, void* e) { } int32_t filterFreeMergeRange(void* h) { + if (h == NULL) { + return TSDB_CODE_SUCCESS; + } + SFilterRMCtx *ctx = (SFilterRMCtx *)h; - SFilterRange *r = ctx->rs; - SFilterRange *rn = NULL; + SFilterRangeNode *r = ctx->rs; + SFilterRangeNode *rn = NULL; while (r) { rn = r->next; @@ -299,7 +411,7 @@ int32_t filterGetFiled(SFilterFields* fields, int32_t type, void *v) { int32_t filterAddField(SFilterInfo *info, tExprNode *node, SFilterFieldId *fid) { CHK_LRET(node == NULL, TSDB_CODE_QRY_APP_ERROR, "empty node"); - CHK_LRET(node->nodeType != TSQL_NODE_COL && node->nodeType != TSQL_NODE_VALUE, TSDB_CODE_QRY_APP_ERROR, "invalid nodeType"); + CHK_LRET(node->nodeType != TSQL_NODE_COL && node->nodeType != TSQL_NODE_VALUE, TSDB_CODE_QRY_APP_ERROR, "invalid nodeType:%d", node->nodeType); int32_t type, idx = -1; uint16_t *num; @@ -308,9 +420,11 @@ int32_t filterAddField(SFilterInfo *info, tExprNode *node, SFilterFieldId *fid) if (node->nodeType == TSQL_NODE_COL) { type = F_FIELD_COLUMN; v = node->pSchema; + node->pSchema = NULL; } else { type = F_FIELD_VALUE; v = node->pVal; + node->pVal = NULL; } num = &info->fields[type].num; @@ -422,7 +536,7 @@ _err_return: int32_t filterInitUnitFunc(SFilterInfo *info) { for (uint16_t i = 0; i < info->unitNum; ++i) { SFilterUnit* unit = &info->units[i]; - SFilterField *left = FILTER_GET_FIELD(info, unit->left); + SFilterField *left = FILTER_UNIT_LEFT_FIELD(info, unit); unit->compare.pCompareFunc = getComparFunc(FILTER_GET_COL_FIELD_TYPE(left), unit->compare.optr); } @@ -432,18 +546,18 @@ int32_t filterInitUnitFunc(SFilterInfo *info) { -void filterDumpInfoToString(SFilterInfo *info) { - CHK_LRETV(info == NULL, "FilterInfo: empty"); +void filterDumpInfoToString(SFilterInfo *info, const char *msg) { + CHK_LRETV(info == NULL, "%s - FilterInfo: empty", msg); - qDebug("FilterInfo:"); - qDebug("Field Col Num:%u", info->fields[F_FIELD_COLUMN].num); + qDebug("%s - FilterInfo:", msg); + qDebug("COLUMN Field Num:%u", info->fields[F_FIELD_COLUMN].num); for (uint16_t i = 0; i < info->fields[F_FIELD_COLUMN].num; ++i) { SFilterField *field = &info->fields[F_FIELD_COLUMN].fields[i]; SSchema *sch = field->desc; qDebug("COL%d => [%d][%s]", i, sch->colId, sch->name); } - qDebug("Field Val Num:%u", info->fields[F_FIELD_VALUE].num); + qDebug("VALUE Field Num:%u", info->fields[F_FIELD_VALUE].num); for (uint16_t i = 0; i < info->fields[F_FIELD_VALUE].num; ++i) { SFilterField *field = &info->fields[F_FIELD_VALUE].fields[i]; tVariant *var = field->desc; @@ -453,8 +567,8 @@ void filterDumpInfoToString(SFilterInfo *info) { qDebug("Unit Num:%u", info->unitNum); for (uint16_t i = 0; i < info->unitNum; ++i) { SFilterUnit *unit = &info->units[i]; - SFilterField *left = FILTER_GET_FIELD(info, unit->left); - SFilterField *right = FILTER_GET_FIELD(info, unit->right); + SFilterField *left = FILTER_UNIT_LEFT_FIELD(info); + SFilterField *right = FILTER_UNIT_RIGHT_FIELD(info, unit); SSchema *sch = left->desc; tVariant *var = right->desc; @@ -478,27 +592,13 @@ void filterFreeInfo(SFilterInfo *info) { //TODO } -int32_t filterSetColFieldData(SFilterInfo *info, int16_t colId, void *data) { - CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL"); - CHK_LRET(info->fields[F_FIELD_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds"); - for (uint16_t i = 0; i < info->fields[F_FIELD_COLUMN].num; ++i) { - SFilterField* fi = &info->fields[F_FIELD_COLUMN].fields[i]; - SSchema* sch = fi->desc; - if (sch->colId == colId) { - fi->data = data; - break; - } - } - - return TSDB_CODE_SUCCESS; -} int32_t filterInitValFieldData(SFilterInfo *info) { for (uint16_t i = 0; i < info->unitNum; ++i) { SFilterUnit* unit = &info->units[i]; - SFilterField* left = FILTER_GET_FIELD(info, unit->left); - SFilterField* right = FILTER_GET_FIELD(info, unit->right); + SFilterField* left = FILTER_UNIT_LEFT_FIELD(info, unit); + SFilterField* right = FILTER_UNIT_RIGHT_FIELD(info, unit); if (left->type != F_FIELD_VALUE && right->type != F_FIELD_VALUE) { continue; @@ -531,7 +631,17 @@ int32_t filterInitValFieldData(SFilterInfo *info) { } else if (type == TSDB_DATA_TYPE_NCHAR) { fi->data = calloc(1, (var->nLen + 1) * TSDB_NCHAR_SIZE); } else { - fi->data = calloc(1, sizeof(int64_t)); + if (var->nType == TSDB_DATA_TYPE_VALUE_ARRAY) { + fi->data = calloc(var->nLen, tDataTypes[type].bytes); + for (int32_t a = 0; a < var->nLen; ++a) { + int64_t *v = taosArrayGet(var->arr, a); + assignVal(fi->data + a * tDataTypes[type].bytes, (char *)v, 0, type); + } + + continue; + } else { + fi->data = calloc(1, sizeof(int64_t)); + } } ERR_LRET(tVariantDump(var, (char*)fi->data, type, true), "dump type[%d] failed", type); @@ -579,6 +689,197 @@ bool filterDoCompare(SFilterUnit *unit, void *left, void *right) { } +#if 0 +int32_t filterAddUnitRange(SFilterInfo *info, SFilterUnit* u, SFilterRMCtx *ctx, int32_t optr) { + int32_t type = FILTER_UNIT_DATA_TYPE(info, u); + uint8_t uoptr = FILTER_UNIT_OPTR(u); + void *val = FILTER_UNIT_VAL(info, u); + int64_t s = 0, e = 0; + + switch (uoptr) { + case TSDB_RELATION_GREATER: + + break; + case TSDB_RELATION_GREATER_EQUAL: + case TSDB_RELATION_LESS: + case TSDB_RELATION_LESS_EQUAL: + case TSDB_RELATION_NOT_EQUAL: + case TSDB_RELATION_EQUAL: + case TSDB_RELATION_IN: + default: + assert(0); + } + + filterAddMergeRange(ctx, &s, &e, optr); + + return TSDB_CODE_SUCCESS; +} + + +int32_t filterMergeSingleGroupUnits(SFilterInfo *info, SFilterGroup* g, uint16_t id1, uint16_t id2, SArray* res) { + bool isnull = false, notnull = false; + int32_t num = 0; + + SFilterRMCtx *cur = filterInitMergeRange(type, 0); + + SFilterUnit* u1 = FILTER_GROUP_UNIT(info, g, id1); + SFilterUnit* u2 = FILTER_GROUP_UNIT(info, g, id2); + uint8_t optr1 = FILTER_UNIT_OPTR(u1); + uint8_t optr2 = FILTER_UNIT_OPTR(u2); + uint16_t cidx = FILTER_UNIT_COL_IDX(u1); + + int32_t type = FILTER_UNIT_DATA_TYPE(info, u1); + +#define SET_OPTR(o) ((o == TSDB_RELATION_ISNULL) ? isnull = true : notnull = true) +#define CHK_OPTR() (isnull == true && notnull == true) + + SET_OPTR(optr1); + SET_OPTR(optr2); + + CHK_JMP(CHK_OPTR()); + + if (!FILTER_NO_MERGE_OPTR(optr1)) { + filterAddUnitRange(info, u1, cur, TSDB_RELATION_AND); + } + + if (!FILTER_NO_MERGE_OPTR(optr2)) { + filterAddUnitRange(info, u2, cur, TSDB_RELATION_AND); + CHK_JMP(MR_EMPTY_RES(cur)); + } + + + for (int32_t i = id2 + 1; i < g->unitNum; ++i) { + SFilterUnit* u = FILTER_GROUP_UNIT(info, g, i); + if (cidx != FILTER_UNIT_COL_IDX(u)) { + continue; + } + + optr2 = FILTER_UNIT_OPTR(u); + SET_OPTR(optr2); + CHK_JMP(CHK_OPTR()); + + if (!FILTER_NO_MERGE_OPTR(optr2)) { + filterAddUnitRange(info, u2, cur, TSDB_RELATION_AND); + CHK_JMP(MR_EMPTY_RES(cur)); + } + } + + SFilterColRange ra; + ra.idx = cidx; + + filterGetMergeRangeNum(cur, &num); + assert(num == 1); + + filterGetMergeRangeRes(cur, &ra.s, &ra.e); + + taosArrayPush(res, &ra); + + filterFreeMergeRange(cur); + + return TSDB_CODE_SUCCESS; + +_err_return: + + g->unitNum = 0; + + filterFreeMergeRange(cur); + + return TSDB_CODE_SUCCESS; + +} + +int32_t filterMergeGroupUnits(SFilterInfo *info, SArray** res) { + uint16_t *f = malloc(1, info->fields[F_FIELD_COLUMN].num * sizeof(uint16_t)); + SArray *gres = NULL; + bool gresUsed = false; + + for (uint16_t i = 0; i < info->groupNum; ++i) { + SFilterGroup* g = info->groups + i; + + memet(f, -1, info->fields[F_FIELD_COLUMN].num); + + gresUsed = false; + + for (uint16_t j = 0; j < g->unitNum; ++j) { + SFilterUnit* u = FILTER_GROUP_UNIT(info, g, j); + int32_t type = FILTER_UNIT_DATA_TYPE(info, u); + if (FILTER_NO_MERGE_DATA_TYPE(type)) { + continue; + } + + uint16_t cidx = FILTER_UNIT_COL_IDX(u); + + if (f[cidx] == -1) { + f[u->left.idx] = j; + } else if (cidx] == -2) { + continue; + } else { + f[cidx] = -2; + + if (gres == NULL) { + gres = taosArrayInit(4, sizeof(SFilterColRange)); + } + + filterMergeSingleGroupUnits(info, g, f[cidx], j, gres); + if (g->unitNum == 0) { + break; + } else { + gresUsed = true; + } + } + } + + if (g->unitNum == 0) { + if (gresUsed) { + taosArrayClear(gres); + } + + continue; + } + + if (res == NULL) { + res = calloc(info->groupNum, sizeof(SArray *)); + res[i] = gres; + gres = NULL; + } + } + + free(f); + if (gres) { + taosArrayDestroy(gres); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t filterPreprocess(SFilterInfo *info) { + SArray* res = NULL; + + filterMergeGroupUnits(info, &res); + + +} + +#endif + +int32_t filterSetColFieldData(SFilterInfo *info, int16_t colId, void *data) { + CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL"); + CHK_LRET(info->fields[F_FIELD_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds"); + + for (uint16_t i = 0; i < info->fields[F_FIELD_COLUMN].num; ++i) { + SFilterField* fi = &info->fields[F_FIELD_COLUMN].fields[i]; + SSchema* sch = fi->desc; + if (sch->colId == colId) { + fi->data = data; + break; + } + } + + return TSDB_CODE_SUCCESS; +} + + bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t* p) { bool all = true; @@ -599,8 +900,8 @@ bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t* p) { ures = FILTER_UNIT_GET_R(info, uidx); } else { SFilterUnit *unit = &info->units[uidx]; - SFilterField *left = FILTER_GET_FIELD(info, unit->left); - SFilterField *right = FILTER_GET_FIELD(info, unit->right); + SFilterField *left = FILTER_UNIT_LEFT_FIELD(info); + SFilterField *right = FILTER_UNIT_RIGHT_FIELD(info, unit); if (isNull(FILTER_GET_COL_FIELD_DATA(left, i), FILTER_GET_COL_FIELD_TYPE(left))) { ures = unit->compare.optr == TSDB_RELATION_ISNULL ? true : false; @@ -659,7 +960,7 @@ int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo) { info->fields[F_FIELD_COLUMN].num = 0; info->fields[F_FIELD_COLUMN].size = FILTER_DEFAULT_FIELD_SIZE; - info->fields[F_FIELD_COLUMN].fields = calloc(info->fields[F_FIELD_COLUMN].size, sizeof(SFilterField)); + info->fields[F_FIELD_COLUMN].fields = calloc(info->fields[F_FIELD_COLUMN].size, COL_FIELD_SIZE); info->fields[F_FIELD_VALUE].num = 0; info->fields[F_FIELD_VALUE].size = FILTER_DEFAULT_FIELD_SIZE; info->fields[F_FIELD_VALUE].fields = calloc(info->fields[F_FIELD_VALUE].size, sizeof(SFilterField)); @@ -678,17 +979,22 @@ int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo) { for (size_t i = 0; i < groupSize; ++i) { SFilterGroup *pg = taosArrayGet(group, i); + pg->unitFlags = calloc(pg->unitNum, sizeof(*pg->unitFlags)); info->groups[i] = *pg; } - ERR_JRET(filterInitUnitFunc(info)); - ERR_JRET(filterInitValFieldData(info)); + filterDumpInfoToString(info, "Before preprocess"); + + //ERR_JRET(filterPreprocess(info)); + + ERR_JRET(filterInitUnitFunc(info)); + info->unitRes = malloc(info->unitNum * sizeof(*info->unitRes)); info->unitFlags = malloc(info->unitNum * sizeof(*info->unitFlags)); - filterDumpInfoToString(info); + filterDumpInfoToString(info, "Final"); _err_return: @@ -697,4 +1003,68 @@ _err_return: return code; } +int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win) { + SFilterRange ra = {0}; + SFilterRMCtx *prev = filterInitMergeRange(TSDB_DATA_TYPE_TIMESTAMP, MR_OPT_TS); + SFilterRMCtx *tmpc = filterInitMergeRange(TSDB_DATA_TYPE_TIMESTAMP, MR_OPT_TS); + SFilterRMCtx *cur = NULL; + int32_t num = 0; + int32_t optr = 0; + int32_t code = 0; + + for (int32_t i = 0; i < info->groupNum; ++i) { + SFilterGroup *group = &info->groups[i]; + if (group->unitNum > 1) { + cur = tmpc; + optr = TSDB_RELATION_AND; + } else { + cur = prev; + optr = TSDB_RELATION_OR; + } + + for (int32_t u = 0; u < group->unitNum; ++u) { + uint16_t uidx = group->unitIdxs[u]; + SFilterUnit *unit = &info->units[uidx]; + SFilterField *right = FILTER_UNIT_RIGHT_FIELD(info, unit); + void *s = FILTER_GET_VAL_FIELD_DATA(right); + void *e = FILTER_GET_VAL_FIELD_DATA(right) + tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes; + + SIMPLE_COPY_VALUES(&ra.s, s); + SIMPLE_COPY_VALUES(&ra.e, e); + + code = filterAddMergeRange(cur, &ra, optr); + if (code) { + break; + } + } + + if (code != TSDB_CODE_SUCCESS) { + break; + } + + if (group->unitNum > 1) { + filterAddMergeRangeCtx(prev, cur, TSDB_RELATION_OR); + filterResetMergeRangeCtx(cur); + } + } + + if (code == TSDB_CODE_SUCCESS) { + filterGetMergeRangeNum(prev, &num); + if (num != 1) { + qError("only one time range accepted, num:%d", num); + ERR_JRET(TSDB_CODE_QRY_INVALID_TIME_CONDITION); + } + + filterGetMergeRangeRes(prev, &win->skey, &win->ekey); + } + +_err_return: + + filterFreeMergeRange(prev); + filterFreeMergeRange(tmpc); + + return code; +} + + diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index a2cb7aee00..7052e8e38b 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -401,6 +401,9 @@ tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) { pExpr->pRight = tSqlExprClone(pSrc->pRight); } + memset(&pExpr->value, 0, sizeof(pExpr->value)); + tVariantAssign(&pExpr->value, &pSrc->value); + //we don't clone pParam now because clone is only used for between/and assert(pSrc->pParam == NULL); return pExpr; diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index ef18575371..6726cf7055 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -188,6 +188,8 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi taosArrayDestroy(param.pGroupbyExpr->columnInfo); } + tfree(param.colCond); + taosArrayDestroy(param.pTableIdList); param.pTableIdList = NULL; diff --git a/src/query/tests/rangeMergeTest.cpp b/src/query/tests/rangeMergeTest.cpp index b64c1a7494..100afd4705 100644 --- a/src/query/tests/rangeMergeTest.cpp +++ b/src/query/tests/rangeMergeTest.cpp @@ -14,81 +14,100 @@ namespace { void intDataTest() { printf("running %s\n", __FUNCTION__); - int32_t s0[3] = {-100, 1, 3}; - int32_t e0[3] = {0 , 2, 4}; + int32_t asize = 0; + int64_t *s =NULL; + int64_t *e =NULL; + int64_t s0[3] = {-100, 1, 3}; + int64_t e0[3] = {0 , 2, 4}; int64_t s1[3] = {INT64_MIN, 0 , 3}; int64_t e1[3] = {100 , 50, 4}; int64_t s2[5] = {1 , 3 , 10,30,70}; int64_t e2[5] = {10, 100, 20,50,120}; int64_t s3[3] = {1 , 20 , 5}; int64_t e3[3] = {10, 100, 25}; + int64_t s4[2] = {10, 0}; + int64_t e4[2] = {20, 5}; + int64_t s5[3] = {0, 6 ,7}; + int64_t e5[5] = {4, 10,20}; - int32_t rs0[3]; - int32_t re0[3]; - int64_t rs1[3]; - int64_t re1[3]; - int64_t rs2[5]; - int64_t re2[5]; - int64_t rs3[5]; - int64_t re3[5]; + int64_t rs[10]; + int64_t re[10]; int32_t num = 0; - - void *h = filterInitMergeRange(TSDB_DATA_TYPE_INT, 0); - for (int32_t i = 0; i < sizeof(s0)/sizeof(s0[0]); ++i) { - filterAddMergeRange(h, s0 + i, e0 + i, TSDB_RELATION_AND); + + s = s0; + e = e0; + asize = sizeof(s0)/sizeof(s[0]); + void *h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 0); filterFreeMergeRange(h); - - h = filterInitMergeRange(TSDB_DATA_TYPE_INT, 0); - for (int32_t i = 0; i < sizeof(s0)/sizeof(s0[0]); ++i) { - filterAddMergeRange(h, s0 + i, e0 + i, TSDB_RELATION_OR); + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 3); - filterGetMergeRangeRes(h, rs0, re0); - ASSERT_EQ(rs0[0], -100); - ASSERT_EQ(re0[0], 0); - ASSERT_EQ(rs0[1], 1); - ASSERT_EQ(re0[1], 2); - ASSERT_EQ(rs0[2], 3); - ASSERT_EQ(re0[2], 4); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], -100); + ASSERT_EQ(re[0], 0); + ASSERT_EQ(rs[1], 1); + ASSERT_EQ(re[1], 2); + ASSERT_EQ(rs[2], 3); + ASSERT_EQ(re[2], 4); filterFreeMergeRange(h); - - h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s1)/sizeof(s1[0]); ++i) { - filterAddMergeRange(h, s1 + i, e1 + i, TSDB_RELATION_AND); + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, MR_OPT_TS); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 1); - filterGetMergeRangeRes(h, rs1, re1); - ASSERT_EQ(rs1[0], 3); - ASSERT_EQ(re1[0], 4); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], -100); + ASSERT_EQ(re[0], 4); filterFreeMergeRange(h); + s = s1; + e = e1; + asize = sizeof(s1)/sizeof(s[0]); h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s1)/sizeof(s1[0]); ++i) { - filterAddMergeRange(h, s1 + i, e1 + i, TSDB_RELATION_OR); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 1); - filterGetMergeRangeRes(h, rs1, re1); - ASSERT_EQ(rs1[0], INT64_MIN); - ASSERT_EQ(re1[0], 100); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 3); + ASSERT_EQ(re[0], 4); filterFreeMergeRange(h); - h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s2)/sizeof(s2[0]); ++i) { - filterAddMergeRange(h, s2 + i, e2 + i, TSDB_RELATION_AND); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 1); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], INT64_MIN); + ASSERT_EQ(re[0], 100); + filterFreeMergeRange(h); + + + s = s2; + e = e2; + asize = sizeof(s2)/sizeof(s[0]); + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 0); @@ -96,21 +115,21 @@ void intDataTest() { h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s2)/sizeof(s2[0]); ++i) { - filterAddMergeRange(h, s2 + i, e2 + i, TSDB_RELATION_OR); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 1); - filterGetMergeRangeRes(h, rs2, re2); - ASSERT_EQ(rs2[0], 1); - ASSERT_EQ(re2[0], 120); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 1); + ASSERT_EQ(re[0], 120); filterFreeMergeRange(h); h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s2)/sizeof(s2[0]); ++i) { - filterAddMergeRange(h, s2 + i, e2 + i, i % 2 ? TSDB_RELATION_OR : TSDB_RELATION_AND); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, i % 2 ? TSDB_RELATION_OR : TSDB_RELATION_AND); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 0); @@ -118,21 +137,23 @@ void intDataTest() { h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s2)/sizeof(s2[0]); ++i) { - filterAddMergeRange(h, s2 + i, e2 + i, i % 2 ? TSDB_RELATION_AND : TSDB_RELATION_OR); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, i % 2 ? TSDB_RELATION_AND : TSDB_RELATION_OR); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 1); - filterGetMergeRangeRes(h, rs2, re2); - ASSERT_EQ(rs2[0], 70); - ASSERT_EQ(re2[0], 120); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 70); + ASSERT_EQ(re[0], 120); filterFreeMergeRange(h); - + s = s3; + e = e3; + asize = sizeof(s3)/sizeof(s[0]); h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s3)/sizeof(s3[0]); ++i) { - filterAddMergeRange(h, s3 + i, e3 + i, TSDB_RELATION_AND); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 0); @@ -140,18 +161,83 @@ void intDataTest() { h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); - for (int32_t i = 0; i < sizeof(s3)/sizeof(s3[0]); ++i) { - filterAddMergeRange(h, s3 + i, e3 + i, TSDB_RELATION_OR); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); } filterGetMergeRangeNum(h, &num); ASSERT_EQ(num, 1); - filterGetMergeRangeRes(h, rs3, re3); - ASSERT_EQ(rs3[0], 1); - ASSERT_EQ(re3[0], 100); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 1); + ASSERT_EQ(re[0], 100); filterFreeMergeRange(h); + + s = s4; + e = e4; + asize = sizeof(s4)/sizeof(s[0]); + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 0); + filterFreeMergeRange(h); + + + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 2); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 0); + ASSERT_EQ(re[0], 5); + ASSERT_EQ(rs[1], 10); + ASSERT_EQ(re[1], 20); + filterFreeMergeRange(h); + + + s = s5; + e = e5; + asize = sizeof(s5)/sizeof(s[0]); + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_AND); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 0); + filterFreeMergeRange(h); + + + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, TSDB_RELATION_OR); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 2); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 0); + ASSERT_EQ(re[0], 4); + ASSERT_EQ(rs[1], 6); + ASSERT_EQ(re[1], 20); + filterFreeMergeRange(h); + + + h = filterInitMergeRange(TSDB_DATA_TYPE_BIGINT, 0); + for (int32_t i = 0; i < asize; ++i) { + filterAddMergeRange(h, s + i, e + i, (i == (asize -1)) ? TSDB_RELATION_AND : TSDB_RELATION_OR); + } + filterGetMergeRangeNum(h, &num); + ASSERT_EQ(num, 1); + filterGetMergeRangeRes(h, rs, re); + ASSERT_EQ(rs[0], 7); + ASSERT_EQ(re[0], 10); + filterFreeMergeRange(h); + + } diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 1d37a6e9a4..4705110ca6 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -268,6 +268,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, "Multiple retrieval of TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW, "Too many time window in query") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_ENOUGH_BUFFER, "Query buffer limit has reached") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, "File inconsistance in replica") +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_TIME_CONDITION, "One valid time range condition expected") // grant diff --git a/tests/script/general/parser/condition.sim b/tests/script/general/parser/condition.sim index 62d1fc03fa..52918a8658 100644 --- a/tests/script/general/parser/condition.sim +++ b/tests/script/general/parser/condition.sim @@ -1527,12 +1527,109 @@ 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:02.000'; sql_error select ts,c1,c7 from stb1 where ts > '2021-05-05 18:19:03.000' and ts > '2021-05-05 18:19:20.000' and ts != '2021-05-05 18:19:22.000'; sql_error select * from stb1 where ts2 like '2021-05-05%'; +sql_error select * from stb1 where ts > '2021-05-05 18:19:03.000' and ts < '2021-05-05 18:19:02'; +sql_error select ts,c1,c2 from stb1 where (ts > '2021-05-05 18:19:25.000' or ts < '2021-05-05 18:19:05.000') and ts > '2021-05-05 18:19:01.000' and ts < '2021-05-05 18:19:27.000'; +sql_error select ts,c1,c2 from stb1 where (ts > '2021-05-05 18:19:20.000' or ts < '2021-05-05 18:19:05.000') and ts != '2021-05-05 18:19:25.000'; +sql_error select ts,c1,c2 from stb1 where ((ts >= '2021-05-05 18:19:05.000' and ts <= '2021-05-05 18:19:10.000') or (ts >= '2021-05-05 18:19:15.000' and ts <= '2021-05-05 18:19:20.000') or (ts >= '2021-05-05 18:19:11.000' and ts <= '2021-05-05 18:19:14.000')); +sql_error select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' or ts < '2021-05-05 18:19:24.000'; +sql_error select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' and ts < '2021-05-05 18:19:10.000'; -sql select * from stb1 where ts > '2021-05-05 18:19:03.000' and ts < '2021-05-05 18:19:02'; -if $rows != 0 then +sql select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' or ts < '2021-05-05 18:19:25.000'; +if $rows != 29 then return -1 endi +sql select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' and ts < '2021-05-05 18:19:26.000'; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-05 18:19:25.000@ then + return -1 +endi +sql select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' or ts < '2021-05-05 18:19:28.000'; +if $rows != 29 then + return -1 +endi +sql select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' or ts > '2021-05-05 18:19:27.000'; +if $rows != 4 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 +if $data30 != @21-05-05 18:19:28.000@ then + return -1 +endi + +sql select ts,c1,c2 from stb1 where ts > '2021-05-05 18:19:20.000' or ts < '2021-05-05 18:19:05.000' or ts != '2021-05-05 18:19:25.000'; +if $rows != 29 then + return -1 +endi + +sql select ts,c1,c2 from stb1 where ts >= '2021-05-05 18:19:25.000' or ts <> '2021-05-05 18:19:25.000'; +if $rows != 29 then + return -1 +endi + +sql select ts,c1,c2 from stb1 where ((ts >= '2021-05-05 18:19:05.000' and ts <= '2021-05-05 18:19:10.999') or (ts >= '2021-05-05 18:19:15.000' and ts <= '2021-05-05 18:19:20.000') or (ts >= '2021-05-05 18:19:11.000' and ts <= '2021-05-05 18:19:14.999')); +if $rows != 16 then + return -1 +endi +if $data00 != @21-05-05 18:19:05.000@ then + return -1 +endi + +sql select ts,c1,c2 from stb1 where (ts >= '2021-05-05 18:19:05.000' and ts <= '2021-05-05 18:19:10.000') or (ts >= '2021-05-05 18:19:12.000' and ts <= '2021-05-05 18:19:14.000') or (ts >= '2021-05-05 18:19:08.000' and ts <= '2021-05-05 18:19:17.000'); +if $rows != 13 then + return -1 +endi +if $data00 != @21-05-05 18:19:05.000@ then + return -1 +endi + +sql select ts,c1,c2 from stb1 where (ts >= '2021-05-05 18:19:05.000' and ts <= '2021-05-05 18:19:10.000') or (ts >= '2021-05-05 18:19:02.000' and ts <= '2021-05-05 18:19:03.000') or (ts >= '2021-05-05 18:19:01.000' and ts <= '2021-05-05 18:19:08.000'); +if $rows != 10 then + return -1 +endi +if $data00 != @21-05-05 18:19:01.000@ then + return -1 +endi + +sql select ts,c1,c2 from stb1 where ((ts >= '2021-05-05 18:19:08.000' and ts <= '2021-05-05 18:19:10.000') or (ts >= '2021-05-05 18:19:02.000' and ts <= '2021-05-05 18:19:03.000') or (ts >= '2021-05-05 18:19:05.000' and ts <= '2021-05-05 18:19:06.000') or (ts >= '2021-05-05 18:19:03.000' and ts <= '2021-05-05 18:19:12.000')) and (ts >= '2021-05-05 18:19:10.000'); +if $rows != 3 then + return -1 +endi +if $data00 != @21-05-05 18:19:10.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:11.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:12.000@ then + return -1 +endi + +sql select ts,c1,c7 from stb1 where ts > '2021-05-05 18:19:25.000' and ts != '2021-05-05 18:19:18'; +if $rows != 3 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 +if $data20 != @21-05-05 18:19:28.000@ then + return -1 +endi + + sql select * from stb1 where ts > '2021-05-05 18:19:03.000' and ts > '2021-05-05 18:19:25'; if $rows != 3 then return -1 @@ -1858,6 +1955,20 @@ if $data00 != @21-05-05 18:19:21.000@ then return -1 endi +sql select * from stb1 where c1!=31 and c1 !=32 and c1 <> 63 and c1 <>1 and c1 <> 21 and c1 <> 2 and c7 <> true and c8 <> '3' and c9 <> '4' and c2<>13 and c3 <> 23 and c4 <> 33 and c5 <> 34 and c6 <> 43 and c2 <> 53 and t1 <> 5 and t2 <>4; +if $rows != 3 then + return -1 +endi +if $data00 != @21-05-05 18:19:07.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:11.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:27.000@ then + return -1 +endi + print "column&join test" sql_error select tb1.ts,tb1.c1,tb2_1.u1 from tb1, tb2_1 where tb1.ts=tb2_1.ts or tb1.c1 > 0;