From 9aa19d5950e120a2001a46b9e723d17b8df42785 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 12 Nov 2021 08:30:34 +0800 Subject: [PATCH] reimplement ceil/floor/round with scalar expr --- src/common/inc/texpr.h | 9 ++-- src/common/src/texpr.c | 98 +++++++++++++++++++++++++++++++++++++++- src/query/src/qAggMain.c | 20 ++++---- 3 files changed, 112 insertions(+), 15 deletions(-) diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index e931f78cc3..4e33285e44 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -57,9 +57,12 @@ struct SSchema; #define TSDB_FUNC_SCALAR_SIN (TSDB_FUNC_FLAG_SCALAR | 0x0007) #define TSDB_FUNC_SCALAR_TAN (TSDB_FUNC_FLAG_SCALAR | 0x0008) #define TSDB_FUNC_SCALAR_SQRT (TSDB_FUNC_FLAG_SCALAR | 0x0009) -#define TSDB_FUNC_SCALAR_CONCAT (TSDB_FUNC_FLAG_SCALAR | 0x000A) -#define TSDB_FUNC_SCALAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x000B) -#define TSDB_FUNC_SCALAR_MAX_NUM 12 +#define TSDB_FUNC_SCALAR_CEIL (TSDB_FUNC_FLAG_SCALAR | 0x000A) +#define TSDB_FUNC_SCALAR_FLOOR (TSDB_FUNC_FLAG_SCALAR | 0x000B) +#define TSDB_FUNC_SCALAR_ROUND (TSDB_FUNC_FLAG_SCALAR | 0x000C) +#define TSDB_FUNC_SCALAR_CONCAT (TSDB_FUNC_FLAG_SCALAR | 0x000D) +#define TSDB_FUNC_SCALAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x000E) +#define TSDB_FUNC_SCALAR_MAX_NUM 15 #define TSDB_FUNC_SCALAR_NAME_MAX_LEN 16 typedef struct { diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 5f28331fdb..c84ebd474b 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -45,7 +45,10 @@ int32_t exprTreeValidateFunctionNode(tExprNode *pExpr) { case TSDB_FUNC_SCALAR_COS: case TSDB_FUNC_SCALAR_SIN: case TSDB_FUNC_SCALAR_TAN: - case TSDB_FUNC_SCALAR_SQRT:{ + case TSDB_FUNC_SCALAR_SQRT: + case TSDB_FUNC_SCALAR_CEIL: + case TSDB_FUNC_SCALAR_FLOOR: + case TSDB_FUNC_SCALAR_ROUND: { return exprValidateMathNode(pExpr); } case TSDB_FUNC_SCALAR_CONCAT: { @@ -1002,7 +1005,7 @@ int32_t exprValidateMathNode(tExprNode *pExpr) { case TSDB_FUNC_SCALAR_ATAN: case TSDB_FUNC_SCALAR_SIN: case TSDB_FUNC_SCALAR_COS: - case TSDB_FUNC_SCALAR_TAN:{ + case TSDB_FUNC_SCALAR_TAN: { if (pExpr->_func.numChildren != 1) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1015,6 +1018,20 @@ int32_t exprValidateMathNode(tExprNode *pExpr) { break; } + case TSDB_FUNC_SCALAR_CEIL: + case TSDB_FUNC_SCALAR_FLOOR: + case TSDB_FUNC_SCALAR_ROUND: { + if (pExpr->_func.numChildren != 1) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + tExprNode* child = pExpr->_func.pChildren[0]; + if (!IS_NUMERIC_TYPE(child->resultType)) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + pExpr->resultType = child->resultType; + pExpr->resultBytes = child->resultBytes; + break; + } default: { assert(false); break; @@ -1227,6 +1244,68 @@ void vectorMathFunc(int16_t functionId, tExprOperandInfo *pInputs, uint8_t numIn SET_TYPED_DATA(outputData, pOutput->type, result); break; } + + case TSDB_FUNC_SCALAR_CEIL: { + assert(numInputs == 1); + assert(IS_NUMERIC_TYPE(pInputs[0].type)); + if (IS_UNSIGNED_NUMERIC_TYPE(pInputs[0].type) || IS_SIGNED_NUMERIC_TYPE(pInputs[0].type)) { + memcpy(outputData, inputData[0], pInputs[0].bytes); + } else { + if (pInputs[0].type == TSDB_DATA_TYPE_FLOAT) { + float v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + float result = ceilf(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } else if (pInputs[0].type == TSDB_DATA_TYPE_DOUBLE) { + double v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + double result = ceil(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } + } + break; + } + case TSDB_FUNC_SCALAR_FLOOR: { + assert(numInputs == 1); + assert(IS_NUMERIC_TYPE(pInputs[0].type)); + if (IS_UNSIGNED_NUMERIC_TYPE(pInputs[0].type) || IS_SIGNED_NUMERIC_TYPE(pInputs[0].type)) { + memcpy(outputData, inputData[0], pInputs[0].bytes); + } else { + if (pInputs[0].type == TSDB_DATA_TYPE_FLOAT) { + float v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + float result = floorf(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } else if (pInputs[0].type == TSDB_DATA_TYPE_DOUBLE) { + double v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + double result = floor(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } + } + break; + } + + case TSDB_FUNC_SCALAR_ROUND: { + assert(numInputs == 1); + assert(IS_NUMERIC_TYPE(pInputs[0].type)); + if (IS_UNSIGNED_NUMERIC_TYPE(pInputs[0].type) || IS_SIGNED_NUMERIC_TYPE(pInputs[0].type)) { + memcpy(outputData, inputData[0], pInputs[0].bytes); + } else { + if (pInputs[0].type == TSDB_DATA_TYPE_FLOAT) { + float v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + float result = roundf(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } else if (pInputs[0].type == TSDB_DATA_TYPE_DOUBLE) { + double v = 0; + GET_TYPED_DATA(v, float, pInputs[0].type, inputData[0]); + double result = round(v); + SET_TYPED_DATA(outputData, pOutput->type, result); + } + } + break; + } default: { assert(false); break; @@ -1295,6 +1374,21 @@ tScalarFunctionInfo aScalarFunctions[] = { "sqrt", vectorMathFunc, }, + { + TSDB_FUNC_SCALAR_CEIL, + "ceil", + vectorMathFunc, + }, + { + TSDB_FUNC_SCALAR_FLOOR, + "flooor", + vectorMathFunc, + }, + { + TSDB_FUNC_SCALAR_ROUND, + "round", + vectorMathFunc + }, { TSDB_FUNC_SCALAR_CONCAT, "concat", diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index b54b595c02..7a4d1a7dc4 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -469,16 +469,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI // TODO use hash table int32_t isValidFunction(const char* name, int32_t len) { - for(int32_t i = 0; i <= TSDB_FUNC_BLKINFO; ++i) { - int32_t nameLen = (int32_t) strlen(aAggs[i].name); - if (len != nameLen) { - continue; - } - - if (strncasecmp(aAggs[i].name, name, len) == 0) { - return i; - } - } for (int32_t i = 0; i < TSDB_FUNC_SCALAR_MAX_NUM; ++i) { int32_t nameLen = (int32_t) strlen(aScalarFunctions[i].name); @@ -490,7 +480,17 @@ int32_t isValidFunction(const char* name, int32_t len) { return aScalarFunctions[i].functionId; } } + + for(int32_t i = 0; i <= TSDB_FUNC_BLKINFO; ++i) { + int32_t nameLen = (int32_t) strlen(aAggs[i].name); + if (len != nameLen) { + continue; + } + if (strncasecmp(aAggs[i].name, name, len) == 0) { + return i; + } + } return -1; } -- GitLab