diff --git a/include/common/tcompare.h b/include/common/tcompare.h index 8476a79e92..5dcbf37b90 100644 --- a/include/common/tcompare.h +++ b/include/common/tcompare.h @@ -23,8 +23,12 @@ extern "C" { #endif -int32_t compareStrPatternComp(const void* pLeft, const void* pRight); -int32_t compareWStrPatternComp(const void* pLeft, const void* pRight); +int32_t compareStrPatternMatch(const void* pLeft, const void* pRight); +int32_t compareStrPatternNotMatch(const void* pLeft, const void* pRight); + +int32_t compareWStrPatternMatch(const void* pLeft, const void* pRight); +int32_t compareWStrPatternNotMatch(const void* pLeft, const void* pRight); + __compar_fn_t getComparFunc(int32_t type, int32_t optr); __compar_fn_t getKeyComparFunc(int32_t keyType, int32_t order); int32_t doCompare(const char* a, const char* b, int32_t type, size_t size); @@ -33,4 +37,4 @@ int32_t doCompare(const char* a, const char* b, int32_t type, size_t size) } #endif -#endif /*_TD_TCOMPARE_H_*/ \ No newline at end of file +#endif /*_TD_TCOMPARE_H_*/ diff --git a/include/common/ttypes.h b/include/common/ttypes.h index 505685f8d5..afa605044a 100644 --- a/include/common/ttypes.h +++ b/include/common/ttypes.h @@ -78,9 +78,12 @@ typedef struct { case TSDB_DATA_TYPE_UINT: \ (_v) = (_finalType)GET_UINT32_VAL(_data); \ break; \ - default: \ + case TSDB_DATA_TYPE_INT: \ (_v) = (_finalType)GET_INT32_VAL(_data); \ break; \ + default: \ + (_v) = (_finalType)varDataLen(_data); \ + break; \ } \ } while (0) @@ -115,9 +118,13 @@ typedef struct { case TSDB_DATA_TYPE_UINT: \ *(uint32_t *)(_v) = (uint32_t)(_data); \ break; \ - default: \ + case TSDB_DATA_TYPE_INT: \ *(int32_t *)(_v) = (int32_t)(_data); \ break; \ + default: \ + (void *)(_v) = (void *)(_data); \ + (void *)(_data) = NULL; \ + break; \ } \ } while (0) @@ -138,6 +145,9 @@ typedef struct { #define IS_VALID_FLOAT(_t) ((_t) >= -FLT_MAX && (_t) <= FLT_MAX) #define IS_VALID_DOUBLE(_t) ((_t) >= -DBL_MAX && (_t) <= DBL_MAX) +#define IS_CONVERT_AS_SIGNED(_t) (IS_SIGNED_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL) || (_t) == (TSDB_DATA_TYPE_TIMESTAMP)) +#define IS_CONVERT_AS_UNSIGNED(_t) (IS_UNSIGNED_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL)) + static FORCE_INLINE bool isNull(const void *val, int32_t type) { switch (type) { case TSDB_DATA_TYPE_BOOL: @@ -205,6 +215,7 @@ void* getDataMax(int32_t type); #define SET_DOUBLE_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_DOUBLE_NULL) +#define SET_BIGINT_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_BIGINT_NULL) #ifdef __cplusplus } diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index c3c8b5c4ce..bdf9a925a8 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -118,6 +118,13 @@ typedef struct SFuncExecFuncs { FExecFinalize finalize; } SFuncExecFuncs; +typedef int32_t (*FScalarExecProcess)(SScalarFuncParam *pInput, int32_t inputNum, SScalarFuncParam *pOutput); + +typedef struct SScalarFuncExecFuncs { + FScalarExecProcess process; +} SScalarFuncExecFuncs; + + int32_t fmFuncMgtInit(); int32_t fmGetHandle(FuncMgtHandle* pHandle); @@ -136,7 +143,8 @@ bool fmIsTimeorderFunc(int32_t funcId); int32_t fmFuncScanType(int32_t funcId); -int32_t fmGetFuncExecFuncs(FuncMgtHandle handle, int32_t funcId, SFuncExecFuncs* pFpSet); +int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet); +int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet); #ifdef __cplusplus } diff --git a/include/nodes/querynodes.h b/include/nodes/querynodes.h index 646ea63c83..f41a5faec2 100644 --- a/include/nodes/querynodes.h +++ b/include/nodes/querynodes.h @@ -93,6 +93,10 @@ typedef enum EOperatorType { OP_TYPE_NOT_LIKE, OP_TYPE_MATCH, OP_TYPE_NMATCH, + OP_TYPE_ISNULL, + OP_TYPE_NOTNULL, + OP_TYPE_BIT_AND, + OP_TYPE_BIT_OR, // json operator OP_TYPE_JSON_GET_VALUE, @@ -277,4 +281,4 @@ bool nodesIsTimelineQuery(const SNode* pQuery); } #endif -#endif /*_TD_QUERY_NODES_H_*/ \ No newline at end of file +#endif /*_TD_QUERY_NODES_H_*/ diff --git a/include/util/compare.h b/include/util/compare.h index 70a8134b35..0ae85418c7 100644 --- a/include/util/compare.h +++ b/include/util/compare.h @@ -49,10 +49,19 @@ int32_t WCSPatternMatch(const wchar_t *pattern, const wchar_t *str, size_t size, int32_t taosArrayCompareString(const void *a, const void *b); -int32_t setCompareBytes1(const void *pLeft, const void *pRight); -int32_t setCompareBytes2(const void *pLeft, const void *pRight); -int32_t setCompareBytes4(const void *pLeft, const void *pRight); -int32_t setCompareBytes8(const void *pLeft, const void *pRight); +int32_t setChkInBytes1(const void *pLeft, const void *pRight); +int32_t setChkInBytes2(const void *pLeft, const void *pRight); +int32_t setChkInBytes4(const void *pLeft, const void *pRight); +int32_t setChkInBytes8(const void *pLeft, const void *pRight); + +int32_t setChkNotInBytes1(const void *pLeft, const void *pRight); +int32_t setChkNotInBytes2(const void *pLeft, const void *pRight); +int32_t setChkNotInBytes4(const void *pLeft, const void *pRight); +int32_t setChkNotInBytes8(const void *pLeft, const void *pRight); + +int32_t compareChkInString(const void *pLeft, const void *pRight); +int32_t compareChkNotInString(const void *pLeft, const void *pRight); + int32_t compareInt8Val(const void *pLeft, const void *pRight); int32_t compareInt16Val(const void *pLeft, const void *pRight); @@ -74,7 +83,6 @@ int32_t compareStrRegexComp(const void *pLeft, const void *pRight); int32_t compareStrRegexCompMatch(const void *pLeft, const void *pRight); int32_t compareStrRegexCompNMatch(const void *pLeft, const void *pRight); -int32_t compareFindItemInSet(const void *pLeft, const void *pRight); int32_t compareInt8ValDesc(const void *pLeft, const void *pRight); int32_t compareInt16ValDesc(const void *pLeft, const void *pRight); diff --git a/include/util/tdef.h b/include/util/tdef.h index 747020a4f9..292a3126c8 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -118,16 +118,18 @@ do { \ #define TSDB_RELATION_GREATER_EQUAL 5 #define TSDB_RELATION_NOT_EQUAL 6 #define TSDB_RELATION_LIKE 7 -#define TSDB_RELATION_ISNULL 8 -#define TSDB_RELATION_NOTNULL 9 -#define TSDB_RELATION_IN 10 +#define TSDB_RELATION_NOT_LIKE 8 +#define TSDB_RELATION_ISNULL 9 +#define TSDB_RELATION_NOTNULL 10 +#define TSDB_RELATION_IN 11 +#define TSDB_RELATION_NOT_IN 12 -#define TSDB_RELATION_AND 11 -#define TSDB_RELATION_OR 12 -#define TSDB_RELATION_NOT 13 +#define TSDB_RELATION_AND 13 +#define TSDB_RELATION_OR 14 +#define TSDB_RELATION_NOT 15 -#define TSDB_RELATION_MATCH 14 -#define TSDB_RELATION_NMATCH 15 +#define TSDB_RELATION_MATCH 16 +#define TSDB_RELATION_NMATCH 17 #define TSDB_BINARY_OP_ADD 4000 #define TSDB_BINARY_OP_SUBTRACT 4001 diff --git a/include/util/types.h b/include/util/types.h index cb25448cc4..25688df56c 100644 --- a/include/util/types.h +++ b/include/util/types.h @@ -66,6 +66,7 @@ static FORCE_INLINE double taos_align_get_double(const char *pBuf) { // #else #define GET_FLOAT_VAL(x) (*(float *)(x)) #define GET_DOUBLE_VAL(x) (*(double *)(x)) + #define SET_BIGINT_VAL(x, y) { (*(int64_t *)(x)) = (int64_t)(y); } #define SET_FLOAT_VAL(x, y) { (*(float *)(x)) = (float)(y); } #define SET_DOUBLE_VAL(x, y) { (*(double *)(x)) = (double)(y); } #define SET_FLOAT_PTR(x, y) { (*(float *)(x)) = (*(float *)(y)); } diff --git a/source/common/src/tcompare.c b/source/common/src/tcompare.c index 3c0e6df735..0ed490bed0 100644 --- a/source/common/src/tcompare.c +++ b/source/common/src/tcompare.c @@ -15,7 +15,7 @@ #include "tcompare.h" -int32_t compareStrPatternComp(const void* pLeft, const void* pRight) { +int32_t compareStrPatternMatch(const void* pLeft, const void* pRight) { SPatternCompareInfo pInfo = {'%', '_'}; assert(varDataLen(pRight) <= TSDB_MAX_FIELD_LEN); @@ -33,7 +33,11 @@ int32_t compareStrPatternComp(const void* pLeft, const void* pRight) { return (ret == TSDB_PATTERN_MATCH) ? 0 : 1; } -int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { +int32_t compareStrPatternNotMatch(const void* pLeft, const void* pRight) { + return compareStrPatternMatch(pLeft, pRight) ? 0 : 1; +} + +int32_t compareWStrPatternMatch(const void* pLeft, const void* pRight) { SPatternCompareInfo pInfo = {'%', '_'}; assert(varDataLen(pRight) <= TSDB_MAX_FIELD_LEN * TSDB_NCHAR_SIZE); @@ -47,6 +51,10 @@ int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { return (ret == TSDB_PATTERN_MATCH) ? 0 : 1; } +int32_t compareWStrPatternNotMatch(const void* pLeft, const void* pRight) { + return compareWStrPatternMatch(pLeft, pRight) ? 0 : 1; +} + __compar_fn_t getComparFunc(int32_t type, int32_t optr) { __compar_fn_t comparFn = NULL; @@ -55,19 +63,42 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_UTINYINT: - return setCompareBytes1; + return setChkInBytes1; case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_USMALLINT: - return setCompareBytes2; + return setChkInBytes2; case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_FLOAT: - return setCompareBytes4; + return setChkInBytes4; case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_TIMESTAMP: - return setCompareBytes8; + return setChkInBytes8; + default: + assert(0); + } + } + + if (optr == TSDB_RELATION_NOT_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) { + switch (type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + return setChkNotInBytes1; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + return setChkNotInBytes2; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_FLOAT: + return setChkNotInBytes4; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_DOUBLE: + case TSDB_DATA_TYPE_TIMESTAMP: + return setChkNotInBytes8; default: assert(0); } @@ -88,9 +119,13 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { } else if (optr == TSDB_RELATION_NMATCH) { comparFn = compareStrRegexCompNMatch; } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ - comparFn = compareStrPatternComp; + comparFn = compareStrPatternMatch; + } else if (optr == TSDB_RELATION_NOT_LIKE) { /* wildcard query using like operator */ + comparFn = compareStrPatternNotMatch; } else if (optr == TSDB_RELATION_IN) { - comparFn = compareFindItemInSet; + comparFn = compareChkInString; + } else if (optr == TSDB_RELATION_NOT_IN) { + comparFn = compareChkNotInString; } else { /* normal relational comparFn */ comparFn = compareLenPrefixedStr; } @@ -104,9 +139,13 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { } else if (optr == TSDB_RELATION_NMATCH) { comparFn = compareStrRegexCompNMatch; } else if (optr == TSDB_RELATION_LIKE) { - comparFn = compareWStrPatternComp; + comparFn = compareWStrPatternMatch; + } else if (optr == TSDB_RELATION_NOT_LIKE) { + comparFn = compareWStrPatternNotMatch; } else if (optr == TSDB_RELATION_IN) { - comparFn = compareFindItemInSet; + comparFn = compareChkInString; + } else if (optr == TSDB_RELATION_NOT_IN) { + comparFn = compareChkNotInString; } else { comparFn = compareLenPrefixedWStr; } @@ -218,4 +257,4 @@ int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { } } } -} \ No newline at end of file +} diff --git a/source/libs/executor/src/tfilter.c b/source/libs/executor/src/tfilter.c index 97dccb5c7b..c42260b214 100644 --- a/source/libs/executor/src/tfilter.c +++ b/source/libs/executor/src/tfilter.c @@ -156,9 +156,11 @@ int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) { } __compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal, - compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp, + compareDoubleVal, compareLenPrefixedStr, compareStrPatternMatch, compareChkInString, compareWStrPatternMatch, compareLenPrefixedWStr, compareUint8Val, compareUint16Val, compareUint32Val, compareUint64Val, - setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexCompMatch, compareStrRegexCompNMatch + setChkInBytes1, setChkInBytes2, setChkInBytes4, setChkInBytes8, compareStrRegexCompMatch, + compareStrRegexCompNMatch, setChkNotInBytes1, setChkNotInBytes2, setChkNotInBytes4, setChkNotInBytes8, + compareChkNotInString, compareStrPatternNotMatch, compareWStrPatternNotMatch }; int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { @@ -186,6 +188,29 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { assert(0); } } + + if (optr == TSDB_RELATION_NOT_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) { + switch (type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + return 21; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + return 22; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_FLOAT: + return 23; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_DOUBLE: + case TSDB_DATA_TYPE_TIMESTAMP: + return 24; + default: + assert(0); + } + } switch (type) { case TSDB_DATA_TYPE_BOOL: @@ -203,8 +228,12 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { comparFn = 20; } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ comparFn = 7; + } else if (optr == TSDB_RELATION_NOT_LIKE) { /* wildcard query using like operator */ + comparFn = 26; } else if (optr == TSDB_RELATION_IN) { comparFn = 8; + } else if (optr == TSDB_RELATION_NOT_IN) { + comparFn = 25; } else { /* normal relational comparFn */ comparFn = 6; } @@ -219,8 +248,12 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { comparFn = 20; } else if (optr == TSDB_RELATION_LIKE) { comparFn = 9; + } else if (optr == TSDB_RELATION_LIKE) { + comparFn = 27; } else if (optr == TSDB_RELATION_IN) { comparFn = 8; + } else if (optr == TSDB_RELATION_NOT_IN) { + comparFn = 25; } else { comparFn = 10; } diff --git a/source/libs/function/inc/tscalar.h b/source/libs/function/inc/tscalar.h index af0ca2dc4c..da98069c86 100644 --- a/source/libs/function/inc/tscalar.h +++ b/source/libs/function/inc/tscalar.h @@ -19,6 +19,9 @@ extern "C" { #endif +typedef struct SScalarCalcContext { + +} SScalarCalcContext; #define sclFatal(...) qFatal(__VA_ARGS__) #define sclError(...) qError(__VA_ARGS__) diff --git a/source/libs/function/src/tbinoperator.c b/source/libs/function/src/tbinoperator.c index 72144bf130..27b5d162a6 100644 --- a/source/libs/function/src/tbinoperator.c +++ b/source/libs/function/src/tbinoperator.c @@ -119,6 +119,70 @@ _getDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { } + +typedef int64_t (*_getBigintValue_fn_t)(void *src, int32_t index); + +int64_t getVectorBigintValue_TINYINT(void *src, int32_t index) { + return (int64_t)*((int8_t *)src + index); +} +int64_t getVectorBigintValue_UTINYINT(void *src, int32_t index) { + return (int64_t)*((uint8_t *)src + index); +} +int64_t getVectorBigintValue_SMALLINT(void *src, int32_t index) { + return (int64_t)*((int16_t *)src + index); +} +int64_t getVectorBigintValue_USMALLINT(void *src, int32_t index) { + return (int64_t)*((uint16_t *)src + index); +} +int64_t getVectorBigintValue_INT(void *src, int32_t index) { + return (int64_t)*((int32_t *)src + index); +} +int64_t getVectorBigintValue_UINT(void *src, int32_t index) { + return (int64_t)*((uint32_t *)src + index); +} +int64_t getVectorBigintValue_BIGINT(void *src, int32_t index) { + return (int64_t)*((int64_t *)src + index); +} +int64_t getVectorBigintValue_UBIGINT(void *src, int32_t index) { + return (int64_t)*((uint64_t *)src + index); +} +int64_t getVectorBigintValue_FLOAT(void *src, int32_t index) { + return (int64_t)*((float *)src + index); +} +int64_t getVectorBigintValue_DOUBLE(void *src, int32_t index) { + return (int64_t)*((double *)src + index); +} +_getDoubleValue_fn_t getVectorBigintValueFn(int32_t srcType) { + _getDoubleValue_fn_t p = NULL; + if(srcType==TSDB_DATA_TYPE_TINYINT) { + p = getVectorBigintValue_TINYINT; + }else if(srcType==TSDB_DATA_TYPE_UTINYINT) { + p = getVectorBigintValue_UTINYINT; + }else if(srcType==TSDB_DATA_TYPE_SMALLINT) { + p = getVectorBigintValue_SMALLINT; + }else if(srcType==TSDB_DATA_TYPE_USMALLINT) { + p = getVectorBigintValue_USMALLINT; + }else if(srcType==TSDB_DATA_TYPE_INT) { + p = getVectorBigintValue_INT; + }else if(srcType==TSDB_DATA_TYPE_UINT) { + p = getVectorBigintValue_UINT; + }else if(srcType==TSDB_DATA_TYPE_BIGINT) { + p = getVectorBigintValue_BIGINT; + }else if(srcType==TSDB_DATA_TYPE_UBIGINT) { + p = getVectorBigintValue_UBIGINT; + }else if(srcType==TSDB_DATA_TYPE_FLOAT) { + p = getVectorBigintValue_FLOAT; + }else if(srcType==TSDB_DATA_TYPE_DOUBLE) { + p = getVectorBigintValue_DOUBLE; + }else { + assert(0); + } + return p; +} + + + + typedef void* (*_getValueAddr_fn_t)(void *src, int32_t index); void* getVectorValueAddr_TINYINT(void *src, int32_t index) { @@ -180,6 +244,337 @@ _getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) { return p; } + +int32_t vectorConvertImpl(SScalarFuncParam* pIn, SScalarFuncParam* pOut) { + int16_t inType = pIn->type; + int16_t inBytes = pIn->bytes; + char *input = pIn->data; + int16_t outType = pOut->type; + int16_t outBytes = pOut->bytes; + char *output = pOut->data; + + switch (outType) { + case TSDB_DATA_TYPE_BOOL: + if (inType == TSDB_DATA_TYPE_BINARY) { + for (int32_t i = 0; i < pIn->num; ++i) { + GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input)); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += sizeof(bool); + } + } else if (inType == TSDB_DATA_TYPE_NCHAR) { + for (int32_t i = 0; i < pIn->num; ++i) { + GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input)); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + } else { + for (int32_t i = 0; i < pIn->num; ++i) { + uint64_t value = 0; + GET_TYPED_DATA(value, uint64_t, inType, input); + SET_TYPED_DATA(output, outType, value); + + input += tDataTypes[inType].bytes; + output += tDataTypes[outType].bytes; + } + } + break; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + if (inType == TSDB_DATA_TYPE_BINARY) { + int32_t bufSize = varDataLen(input) + 1; + char *tmp = malloc(bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input) >= bufSize) { + bufSize = varDataLen(input) + 1; + tmp = realloc(tmp, bufSize); + } + + memcpy(tmp, varDataVal(input), varDataLen(input)); + tmp[varDataLen(input)] = 0; + + int64_t value = strtoll(tmp, NULL, 10); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else if (inType == TSDB_DATA_TYPE_NCHAR) { + int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + char *tmp = calloc(1, bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) { + bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + tmp = realloc(tmp, bufSize); + } + + int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp); + if (len < 0){ + qError("castConvert taosUcs4ToMbs error 1"); + tfree(tmp); + return; + } + + tmp[len] = 0; + int64_t value = strtoll(tmp, NULL, 10); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else { + for (int32_t i = 0; i < pIn->num; ++i) { + int64_t value = 0; + GET_TYPED_DATA(value, int64_t, inType, input); + SET_TYPED_DATA(output, outType, value); + + input += tDataTypes[inType].bytes; + output += tDataTypes[outType].bytes; + } + } + break; + case TSDB_DATA_TYPE_USMALLINT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_UBIGINT: + if (inType == TSDB_DATA_TYPE_BINARY) { + int32_t bufSize = varDataLen(input) + 1; + char *tmp = malloc(bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input) >= bufSize) { + bufSize = varDataLen(input) + 1; + tmp = realloc(tmp, bufSize); + } + + memcpy(tmp, varDataVal(input), varDataLen(input)); + tmp[varDataLen(input)] = 0; + uint64_t value = strtoull(tmp, NULL, 10); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else if (inType == TSDB_DATA_TYPE_NCHAR) { + int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + char *tmp = calloc(1, bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) { + bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + tmp = realloc(tmp, bufSize); + } + + int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp); + if (len < 0){ + qError("castConvert taosUcs4ToMbs error 1"); + tfree(tmp); + return; + } + + tmp[len] = 0; + uint64_t value = strtoull(tmp, NULL, 10); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else { + for (int32_t i = 0; i < pIn->num; ++i) { + uint64_t value = 0; + GET_TYPED_DATA(value, uint64_t, inType, input); + SET_TYPED_DATA(output, outType, value); + + input += tDataTypes[inType].bytes; + output += tDataTypes[outType].bytes; + } + } + break; + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE: + if (inType == TSDB_DATA_TYPE_BINARY) { + int32_t bufSize = varDataLen(input) + 1; + char *tmp = malloc(bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input) >= bufSize) { + bufSize = varDataLen(input) + 1; + tmp = realloc(tmp, bufSize); + } + + memcpy(tmp, varDataVal(input), varDataLen(input)); + tmp[varDataLen(input)] = 0; + + double value = strtod(tmp, NULL); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else if (inType == TSDB_DATA_TYPE_NCHAR) { + int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + char *tmp = calloc(1, bufSize); + if (NULL == tmp) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pIn->num; ++i) { + if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) { + bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1; + tmp = realloc(tmp, bufSize); + } + + int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp); + if (len < 0){ + qError("castConvert taosUcs4ToMbs error 1"); + tfree(tmp); + return; + } + + tmp[len] = 0; + double value = strtod(tmp, NULL); + SET_TYPED_DATA(output, outType, value); + + input += varDataLen(input) + VARSTR_HEADER_SIZE; + output += tDataTypes[outType].bytes; + } + + tfree(tmp); + } else { + for (int32_t i = 0; i < pIn->num; ++i) { + int64_t value = 0; + GET_TYPED_DATA(value, int64_t, inType, input); + SET_TYPED_DATA(output, outType, value); + + input += tDataTypes[inType].bytes; + output += tDataTypes[outType].bytes; + } + } + break; + default: + qError("invalid convert output type:%d", outType); + return TSDB_CODE_QRY_APP_ERROR; + } + + return TSDB_CODE_SUCCESS; +} + +int8_t gConvertTypes[TSDB_DATA_TYPE_BLOB+1][TSDB_DATA_TYPE_BLOB+1] = { +/* NULL BOOL TINY SMAL INT BIG FLOA DOUB BINA TIME NCHA UTIN USMA UINT UBIG VARC VARB JSON DECI BLOB */ +/*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*BOOL*/ 0, 0, 0, 3, 4, 5, 6, 7, 7, 9, 7, 0, 12, 13, 14, 7, 7, 0, 0, 0, +/*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 7, 9, 7, 3, 4, 5, 7, 7, 7, 0, 0, 0, +/*SMAL*/ 0, 0, 0, 0, 4, 5, 6, 7, 7, 9, 7, 3, 4, 5, 7, 7, 7, 0, 0, 0, +/*INT */ 0, 0, 0, 0, 0, 5, 6, 7, 7, 9, 7, 4, 4, 5, 7, 7, 7, 0, 0, 0, +/*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 5, 5, 5, 7, 7, 7, 0, 0, 0, +/*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 7, 6, 7, 6, 6, 6, 6, 7, 7, 0, 0, 0, +/*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, +/*BINA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, +/*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 9, 7, 7, 7, 0, 0, 0, +/*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, +/*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 7, 7, 0, 0, 0, +/*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 7, 7, 0, 0, 0, +/*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 7, 7, 0, 0, 0, +/*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, +/*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int32_t vectorConvert(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, SScalarFuncParam* pLeftOut, SScalarFuncParam* pRightOut) { + if (pLeft->type == pRight->type) { + return TSDB_CODE_SUCCESS; + } + + SScalarFuncParam *param1 = NULL, *paramOut1 = NULL; + SScalarFuncParam *param2 = NULL, *paramOut2 = NULL; + int32_t code = 0; + + if (pLeft->type < pRight->type) { + param1 = pLeft; + param2 = pRight; + paramOut1 = pLeftOut; + paramOut2 = pRightOut; + } else { + param1 = pRight; + param2 = pLeft; + paramOut1 = pRightOut; + paramOut2 = pLeftOut; + } + + int8_t type = gConvertTypes[param1->type][param2->type]; + if (0 == type) { + return TSDB_CODE_SUCCESS; + } + + if (type != param1->type) { + paramOut1->bytes = param1->bytes; + paramOut1->type = type; + paramOut1->num = param1->num; + paramOut1->data = malloc(paramOut1->num * tDataTypes[paramOut1->type].bytes); + if (NULL == paramOut1->data) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + code = vectorConvertImpl(param1, paramOut1); + if (code) { + tfree(paramOut1->data); + return code; + } + } + + if (type != param2->type) { + paramOut2->bytes = param2->bytes; + paramOut2->type = type; + paramOut2->num = param2->num; + paramOut2->data = malloc(paramOut2->num * tDataTypes[paramOut2->type].bytes); + if (NULL == paramOut2->data) { + tfree(paramOut1->data) + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + code = vectorConvertImpl(param2, paramOut2); + if (code) { + tfree(paramOut1->data) + tfree(paramOut2->data); + return code; + } + } + + return TSDB_CODE_SUCCESS; +} + void vectorAdd(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; @@ -463,6 +858,255 @@ void vectorConcat(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, } + +void vectorBitAnd(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; + int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; + + int64_t *output=(int64_t *)out; + _getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type); + _getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type); + _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeft->type); + _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRight->type); + + if (pLeft->num == pRight->num) { + for (; i < pRight->num && i >= 0; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) || + isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + + SET_BIGINT_VAL(output, getVectorBigintValueFnLeft(pLeft->data, i) & getVectorBigintValueFnRight(pRight->data, i)); + } + } else if (pLeft->num == 1) { + for (; i >= 0 && i < pRight->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data, 0) & getVectorBigintValueFnRight(pRight->data,i)); + } + } else if (pRight->num == 1) { + for (; i >= 0 && i < pLeft->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) & getVectorBigintValueFnRight(pRight->data,0)); + } + } +} + +void vectorBitOr(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; + int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; + + int64_t *output=(int64_t *)out; + _getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type); + _getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type); + _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeft->type); + _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRight->type); + + if (pLeft->num == pRight->num) { + for (; i < pRight->num && i >= 0; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) || + isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + + SET_BIGINT_VAL(output, getVectorBigintValueFnLeft(pLeft->data, i) | getVectorBigintValueFnRight(pRight->data, i)); + } + } else if (pLeft->num == 1) { + for (; i >= 0 && i < pRight->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data, 0) | getVectorBigintValueFnRight(pRight->data,i)); + } + } else if (pRight->num == 1) { + for (; i >= 0 && i < pLeft->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) { + SET_BIGINT_NULL(output); + continue; + } + SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) | getVectorBigintValueFnRight(pRight->data,0)); + } + } +} + + +void vectorCompareImpl(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord, int32_t optr) { + int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; + int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; + int8_t funcIdx = filterGetCompFuncIdx(pLeft->type, optr); + __compar_fn_t fp = gDataCompare[funcIdx]; + bool res = false; + + bool *output=(bool *)out; + _getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type); + _getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type); + + if (pLeft->num == pRight->num) { + for (; i < pRight->num && i >= 0; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) || + isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) { + res = false; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + continue; + } + + res = filterDoCompare(fp, optr, getVectorValueAddrFnLeft(pLeft->data, i), getVectorValueAddrFnRight(pRight->data,i)); + + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + } + } else if (pLeft->num == 1) { + void *leftData = getVectorValueAddrFnLeft(pLeft->data, 0); + + for (; i >= 0 && i < pRight->num; i += step, output += 1) { + if (isNull(leftData, pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) { + res = false; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + continue; + } + + res = filterDoCompare(fp, optr, leftData, getVectorValueAddrFnRight(pRight->data,i)); + + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + } + } else if (pRight->num == 1) { + void *rightData = getVectorValueAddrFnRight(pRight->data, 0); + + for (; i >= 0 && i < pLeft->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(rightData, pRight->type)) { + res = false; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + continue; + } + + res = filterDoCompare(fp, optr, getVectorValueAddrFnLeft(pLeft->data,i), rightData); + + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + } + } +} + +void vectorCompare(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord, int32_t optr) { + SScalarFuncParam pLeftOut = {0}; + SScalarFuncParam pRightOut = {0}; + + vectorConvert(pLeft, pRight, &pLeftOut, &pRightOut); + + SScalarFuncParam *param1 = NULL; + SScalarFuncParam *param2 = NULL; + + int32_t type = 0; + if (pLeftOut->type) { + param1 = &pLeftOut; + } else { + param1 = pLeft; + } + + if (pRightOut->type) { + param2 = &pRightOut; + } else { + param2 = pRight; + } + + vectorCompareImpl(pLeftOut, pRightOut, out, _ord, TSDB_RELATION_GREATER); +} + +void vectorGreater(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_GREATER); +} + +void vectorGreaterEqual(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_GREATER_EQUAL); +} + +void vectorLower(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LESS); +} + +void vectorLowerEqual(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LESS_EQUAL); +} + +void vectorEqual(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_EQUAL); +} + +void vectorNotEqual(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_EQUAL); +} + +void vectorIn(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_IN); +} + +void vectorNotIn(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_IN); +} + +void vectorLike(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LIKE); +} + +void vectorNotLike(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_LIKE); +} + +void vectorMatch(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_MATCH); +} + +void vectorNotMatch(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NMATCH); +} + +void vectorIsNull(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; + int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; + bool res = false; + + bool *output=(bool *)out; + _getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type); + + for (; i >= 0 && i < pLeft->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) { + res = true; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + continue; + } + + res = false; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + } +} + +void vectorNotNull(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) { + int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1; + int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; + bool res = false; + + bool *output=(bool *)out; + _getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type); + + for (; i >= 0 && i < pLeft->num; i += step, output += 1) { + if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) { + res = false; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + continue; + } + + res = true; + SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res); + } +} + + _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) { switch (binFunctionId) { case OP_TYPE_ADD: @@ -475,6 +1119,38 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) { return vectorDivide; case OP_TYPE_MOD: return vectorRemainder; + case OP_TYPE_GREATER_THAN: + return vectorGreater; + case OP_TYPE_GREATER_EQUAL: + return vectorGreaterEqual; + case OP_TYPE_LOWER_THAN: + return vectorLower; + case OP_TYPE_LOWER_EQUAL: + return vectorLowerEqual; + case OP_TYPE_EQUAL: + return vectorEqual; + case OP_TYPE_NOT_EQUAL: + return vectorNotEqual; + case OP_TYPE_IN: + return vectorIn; + case OP_TYPE_NOT_IN: + return vectorNotIn; + case OP_TYPE_LIKE: + return vectorLike; + case OP_TYPE_NOT_LIKE: + return vectorNotLike; + case OP_TYPE_MATCH: + return vectorMatch; + case OP_TYPE_NMATCH: + return vectorNotMatch; + case OP_TYPE_ISNULL: + return vectorIsNull; + case OP_TYPE_NOTNULL: + return vectorNotNull; + case OP_TYPE_BIT_AND: + return vectorBitAnd; + case OP_TYPE_BIT_OR: + return vectorBitOr; default: assert(0); return NULL; diff --git a/source/libs/function/src/tscalar.c b/source/libs/function/src/tscalar.c index 6a4a8975af..e374ce2734 100644 --- a/source/libs/function/src/tscalar.c +++ b/source/libs/function/src/tscalar.c @@ -1,26 +1,164 @@ #include "nodes.h" #include "tscalar.h" -EDealRes sclCalculateConstants(SNode** pNode, void* pContext) { - if (QUERY_NODE_VALUE == nodeType(*pNode)) { - return DEAL_RES_CONTINUE; +int32_t sclGetOperatorParamNum(EOperatorType type) { + if (OP_TYPE_ISNULL == type || OP_TYPE_NOTNULL == type) { + return 1; } - if (QUERY_NODE_OPERATOR != nodeType(*pNode)) { - sclError("invalid node type for calculating constants, type:%d", ); + return 2; +} + +int32_t sclPrepareFunctionParams(SScalarFuncParam **pParams, SNodeList* pParameterList) { + *pParams = calloc(pParameterList->length, sizeof(SScalarFuncParam)); + if (NULL == *pParams) { + sclError("calloc %d failed", pParameterList->length * sizeof(SScalarFuncParam)); + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + SListCell *cell = pParameterList->pHead; + for (int32_t i = 0; i < pParameterList->length; ++i) { + if (NULL == cell || NULL == cell->pNode) { + sclError("invalid cell, cell:%p, pNode:%p", cell, cell->pNode); + tfree(*pParams); + return TSDB_CODE_QRY_INVALID_INPUT; + } + + if (QUERY_NODE_VALUE != nodeType(cell->pNode)) { + sclError("invalid node type in cell, type:%d", nodeType(cell->pNode)); + tfree(*pParams); + return TSDB_CODE_QRY_APP_ERROR; + } + + SValueNode *valueNode = (SValueNode *)cell->pNode; + pParams[i].data = nodesGetValueFromNode(valueNode); + pParams[i].num = 1; + pParams[i].type = valueNode->node.resType.type; + pParams[i].bytes = valueNode->node.resType.bytes; + + cell = cell->pNext; + } + + return TSDB_CODE_SUCCESS; +} + +EDealRes sclRewriteFunction(SNode** pNode, void* pContext) { + SFunctionNode *node = (SFunctionNode *)*pNode; + if (NULL == node->pParameterList || node->pParameterList->length <= 0) { + sclError("invalid function parameter list, list:%p, paramNum:%d", node->pParameterList, node->pParameterList ? node->pParameterList->length : 0); *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; return DEAL_RES_ERROR; - } + } + + SScalarFuncExecFuncs ffpSet = {0}; + int32_t code = fmGetScalarFuncExecFuncs(node->funcId, &ffpSet); + if (code) { + sclError( "fmGetFuncExecFuncs failed, funcId:%d, code:%s", node->funcId, tstrerror(code)); + *(int32_t *)pContext = code; + return DEAL_RES_ERROR; + } + + SScalarFuncParam *input = NULL; + if (sclPrepareFunctionParams(&input, node->pParameterList)) { + return DEAL_RES_ERROR; + } + + SScalarFuncParam output = {0}; + code = (*ffpSet.process)(input, node->pParameterList->length, &output); + if (code) { + sclError( "scalar function exec failed, funcId:%d, code:%s", node->funcId, tstrerror(code)); + *(int32_t *)pContext = code; + return DEAL_RES_ERROR; + } + + SValueNode *res = nodesMakeNode(QUERY_NODE_VALUE); + if (NULL == res) { + sclError("make value node failed"); + *(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + + res->node.resType = node->node.resType; + + SET_TYPED_DATA(nodesGetValueFromNode(res), output.type, output.data); + + nodesDestroyNode(*pNode); + *pNode = (SNode*)res; + + tfree(output.data); + + return DEAL_RES_CONTINUE; +} + +EDealRes sclRewriteLogic(SNode** pNode, void* pContext) { + SLogicConditionNode *node = (SLogicConditionNode *)*pNode; + if (NULL == node->pParameterList || node->pParameterList->length <= 0) { + sclError("invalid logic parameter list, list:%p, paramNum:%d", node->pParameterList, node->pParameterList ? node->pParameterList->length : 0); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + if (LOGIC_COND_TYPE_NOT == node->condType && node->pParameterList->length > 1) { + sclError("invalid NOT operation parameter number, paramNum:%d", node->pParameterList->length); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + bool value = false; + SListCell *cell = node->pParameterList->pHead; + for (int32_t i = 0; i < node->pParameterList->length; ++i) { + if (NULL == cell || NULL == cell->pNode) { + sclError("invalid cell, cell:%p, pNode:%p", cell, cell->pNode); + return TSDB_CODE_QRY_INVALID_INPUT; + } + + if (QUERY_NODE_VALUE != nodeType(cell->pNode)) { + sclError("invalid node type in cell, type:%d", nodeType(cell->pNode)); + return TSDB_CODE_QRY_APP_ERROR; + } + + SValueNode *valueNode = (SValueNode *)cell->pNode; + GET_TYPED_DATA(value, bool, valueNode->node.resType.type, nodesGetValueFromNode(valueNode)); + if (LOGIC_COND_TYPE_AND == node->condType && (false == value)) { + break; + } else if (LOGIC_COND_TYPE_OR == node->condType && value) { + break; + } else if (LOGIC_COND_TYPE_NOT == node->condType) { + value = !value; + } + + cell = cell->pNext; + } + + SValueNode *res = nodesMakeNode(QUERY_NODE_VALUE); + if (NULL == res) { + sclError("make value node failed"); + *(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + + res->node.resType = node->node.resType; + + SET_TYPED_DATA(nodesGetValueFromNode(res), res->node.resType.type, value); + + nodesDestroyNode(*pNode); + *pNode = (SNode*)res; + + return DEAL_RES_CONTINUE; +} + +EDealRes sclRewriteOperator(SNode** pNode, void* pContext) { SOperatorNode *oper = (SOperatorNode *)*pNode; - if (NULL == oper->pLeft || NULL == oper->pRight) { + int32_t paramNum = sclGetOperatorParamNum(oper->opType); + if (NULL == oper->pLeft || (paramNum == 2 && NULL == oper->pRight)) { sclError("invalid operation node, left:%p, right:%p", oper->pLeft, oper->pRight); *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; return DEAL_RES_ERROR; } - - if (QUERY_NODE_VALUE != nodeType(oper->pLeft) || QUERY_NODE_VALUE != nodeType(oper->pRight)) { - sclError("invalid operation node, leftType:%d, rightType:%d", nodeType(oper->pLeft), nodeType(oper->pRight)); + + if (QUERY_NODE_VALUE != nodeType(oper->pLeft) || (paramNum == 2 && QUERY_NODE_VALUE != nodeType(oper->pRight))) { + sclError("invalid operation node, leftType:%d, rightType:%d", nodeType(oper->pLeft), oper->pRight ? nodeType(oper->pRight) : 0); *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; return DEAL_RES_ERROR; } @@ -37,10 +175,12 @@ EDealRes sclCalculateConstants(SNode** pNode, void* pContext) { SValueNode *leftValue = (SValueNode *)oper->pLeft; SValueNode *rightValue = (SValueNode *)oper->pRight; - SScalarFuncParam leftParam = {0}, rightParam = {0}; + SScalarFuncParam leftParam = {0}, rightParam = {0}; _bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(oper->opType); - setScalarFuncParam(&leftParam, leftValue->node.resType, 0, nodesGetValueFromNode(leftValue), 1); - setScalarFuncParam(&rightParam, rightValue->node.resType, 0, nodesGetValueFromNode(rightValue), 1); + setScalarFuncParam(&leftParam, leftValue->node.resType.type, 0, nodesGetValueFromNode(leftValue), 1); + if (2 == paramNum) { + setScalarFuncParam(&rightParam, rightValue->node.resType.type, 0, nodesGetValueFromNode(rightValue), 1); + } OperatorFn(&leftParam, &rightParam, nodesGetValueFromNode(res), TSDB_ORDER_ASC); @@ -50,6 +190,91 @@ EDealRes sclCalculateConstants(SNode** pNode, void* pContext) { return DEAL_RES_CONTINUE; } + +EDealRes sclConstantsRewriter(SNode** pNode, void* pContext) { + if (QUERY_NODE_VALUE == nodeType(*pNode)) { + return DEAL_RES_CONTINUE; + } + + if (QUERY_NODE_FUNCTION == nodeType(*pNode)) { + return sclRewriteFunction(pNode, pContext); + } + + if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) { + return sclRewriteLogic(pNode, pContext); + } + + if (QUERY_NODE_OPERATOR != nodeType(*pNode)) { + sclError("invalid node type for calculating constants, type:%d", ); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + return sclRewriteOperator(pNode, pContext); +} + +EDealRes sclCalculate(SNode** pNode, void* pContext) { + if (QUERY_NODE_VALUE == nodeType(*pNode)) { + return DEAL_RES_CONTINUE; + } + + if (QUERY_NODE_FUNCTION == nodeType(*pNode)) { + return sclCalculateFunction(pNode, pContext); + } + + if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) { + return sclCalculateLogic(pNode, pContext); + } + + if (QUERY_NODE_OPERATOR != nodeType(*pNode)) { + sclError("invalid node type for calculating constants, type:%d", ); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + SOperatorNode *oper = (SOperatorNode *)*pNode; + int32_t paramNum = sclGetOperatorParamNum(oper->opType); + if (NULL == oper->pLeft || (paramNum == 2 && NULL == oper->pRight)) { + sclError("invalid operation node, left:%p, right:%p", oper->pLeft, oper->pRight); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + if (QUERY_NODE_VALUE != nodeType(oper->pLeft) || (paramNum == 2 && QUERY_NODE_VALUE != nodeType(oper->pRight))) { + sclError("invalid operation node, leftType:%d, rightType:%d", nodeType(oper->pLeft), oper->pRight ? nodeType(oper->pRight) : 0); + *(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT; + return DEAL_RES_ERROR; + } + + SValueNode *res = nodesMakeNode(QUERY_NODE_VALUE); + if (NULL == res) { + sclError("make value node failed"); + *(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + + res->node.resType = oper->node.resType; + + SValueNode *leftValue = (SValueNode *)oper->pLeft; + SValueNode *rightValue = (SValueNode *)oper->pRight; + + SScalarFuncParam leftParam = {0}, rightParam = {0}; + _bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(oper->opType); + setScalarFuncParam(&leftParam, leftValue->node.resType.type, 0, nodesGetValueFromNode(leftValue), 1); + if (2 == paramNum) { + setScalarFuncParam(&rightParam, rightValue->node.resType.type, 0, nodesGetValueFromNode(rightValue), 1); + } + + OperatorFn(&leftParam, &rightParam, nodesGetValueFromNode(res), TSDB_ORDER_ASC); + + nodesDestroyNode(*pNode); + *pNode = (SNode*)res; + + return DEAL_RES_CONTINUE; +} + + + int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { if (NULL == pNode) { SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -57,7 +282,26 @@ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { int32_t code = 0; - nodesRewriteNodePostOrder(&pNode, sclCalculateConstants, (void *)&code); + nodesRewriteNodePostOrder(&pNode, sclConstantsRewriter, (void *)&code); + + if (code) { + nodesDestroyNode(pNode); + SCL_ERR_RET(code); + } + + *pRes = pNode; + + SCL_RET(code); +} + +int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SSDataBlock *pDst) { + if (NULL == pNode) { + SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + + int32_t code = 0; + + nodesRewriteNodePostOrder(&pNode, sclCalculate, (void *)&code); if (code) { nodesDestroyNode(pNode); diff --git a/source/util/src/compare.c b/source/util/src/compare.c index a1c1625c34..ab353fcbb3 100644 --- a/source/util/src/compare.c +++ b/source/util/src/compare.c @@ -24,22 +24,48 @@ #include "types.h" #include "ulog.h" -int32_t setCompareBytes1(const void *pLeft, const void *pRight) { +int32_t setChkInBytes1(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 1) ? 1 : 0; } -int32_t setCompareBytes2(const void *pLeft, const void *pRight) { +int32_t setChkInBytes2(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 2) ? 1 : 0; } -int32_t setCompareBytes4(const void *pLeft, const void *pRight) { +int32_t setChkInBytes4(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 4) ? 1 : 0; } -int32_t setCompareBytes8(const void *pLeft, const void *pRight) { +int32_t setChkInBytes8(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 8) ? 1 : 0; } +int32_t setChkNotInBytes1(const void *pLeft, const void *pRight) { + return NULL == taosHashGet((SHashObj *)pRight, pLeft, 1) ? 1 : 0; +} + +int32_t setChkNotInBytes2(const void *pLeft, const void *pRight) { + return NULL == taosHashGet((SHashObj *)pRight, pLeft, 2) ? 1 : 0; +} + +int32_t setChkNotInBytes4(const void *pLeft, const void *pRight) { + return NULL == taosHashGet((SHashObj *)pRight, pLeft, 4) ? 1 : 0; +} + +int32_t setChkNotInBytes8(const void *pLeft, const void *pRight) { + return NULL == taosHashGet((SHashObj *)pRight, pLeft, 8) ? 1 : 0; +} + + +int32_t compareChkInString(const void *pLeft, const void* pRight) { + return NULL != taosHashGet((SHashObj *)pRight, varDataVal(pLeft), varDataLen(pLeft)) ? 1 : 0; +} + +int32_t compareChkNotInString(const void *pLeft, const void* pRight) { + return NULL == taosHashGet((SHashObj *)pRight, varDataVal(pLeft), varDataLen(pLeft)) ? 1 : 0; +} + + int32_t compareInt8Val(const void *pLeft, const void *pRight) { int8_t left = GET_INT8_VAL(pLeft), right = GET_INT8_VAL(pRight); if (left > right) return 1; @@ -392,7 +418,3 @@ int32_t taosArrayCompareString(const void* a, const void* b) { return compareLenPrefixedStr(x, y); } - -int32_t compareFindItemInSet(const void *pLeft, const void* pRight) { - return NULL != taosHashGet((SHashObj *)pRight, varDataVal(pLeft), varDataLen(pLeft)) ? 1 : 0; -}