diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 35832fa298..85a9cd0b23 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -57,18 +57,19 @@ typedef enum EFunctionType { // math function FUNCTION_TYPE_ABS = 1000, - FUNCTION_TYPE_ACOS, - FUNCTION_TYPE_ASION, - FUNCTION_TYPE_ATAN, - FUNCTION_TYPE_CEIL, - FUNCTION_TYPE_COS, - FUNCTION_TYPE_FLOOR, FUNCTION_TYPE_LOG, FUNCTION_TYPE_POW, - FUNCTION_TYPE_ROUND, - FUNCTION_TYPE_SIN, FUNCTION_TYPE_SQRT, + FUNCTION_TYPE_CEIL, + FUNCTION_TYPE_FLOOR, + FUNCTION_TYPE_ROUND, + + FUNCTION_TYPE_SIN, + FUNCTION_TYPE_COS, FUNCTION_TYPE_TAN, + FUNCTION_TYPE_ASIN, + FUNCTION_TYPE_ACOS, + FUNCTION_TYPE_ATAN, // string function FUNCTION_TYPE_CHAR_LENGTH = 1500, diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index e55c0b9e76..12c03afcb6 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -42,6 +42,21 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type); int32_t vectorGetConvertType(int32_t type1, int32_t type2); int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut); +int32_t absFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t logFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t powFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t sqrtFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); + +int32_t sinFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t cosFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t tanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t asinFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t acosFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); + +int32_t ceilFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t floorFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t roundFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/CMakeLists.txt b/source/libs/function/CMakeLists.txt index 5c01ec78f0..e1c7626f01 100644 --- a/source/libs/function/CMakeLists.txt +++ b/source/libs/function/CMakeLists.txt @@ -11,8 +11,8 @@ target_include_directories( target_link_libraries( function + PRIVATE os util common nodes scalar PUBLIC uv_a - PRIVATE os util common nodes ) add_executable(runUdf test/runUdf.c) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index e27d53c1ee..70b2a48da7 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -15,6 +15,7 @@ #include "builtins.h" #include "builtinsimpl.h" +#include "scalar.h" #include "taoserror.h" #include "tdatablock.h" @@ -151,6 +152,136 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .processFunc = lastFunction, .finalizeFunc = functionFinalize }, + { + .name = "abs", + .type = FUNCTION_TYPE_ABS, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = absFunction, + .finalizeFunc = NULL + }, + { + .name = "log", + .type = FUNCTION_TYPE_LOG, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = logFunction, + .finalizeFunc = NULL + }, + { + .name = "power", + .type = FUNCTION_TYPE_POW, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = powFunction, + .finalizeFunc = NULL + }, + { + .name = "sqrt", + .type = FUNCTION_TYPE_SQRT, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = sqrtFunction, + .finalizeFunc = NULL + }, + { + .name = "ceil", + .type = FUNCTION_TYPE_CEIL, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = ceilFunction, + .finalizeFunc = NULL + }, + { + .name = "floor", + .type = FUNCTION_TYPE_FLOOR, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = floorFunction, + .finalizeFunc = NULL + }, + { + .name = "round", + .type = FUNCTION_TYPE_ROUND, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = roundFunction, + .finalizeFunc = NULL + }, + { + .name = "sin", + .type = FUNCTION_TYPE_SIN, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = sinFunction, + .finalizeFunc = NULL + }, + { + .name = "cos", + .type = FUNCTION_TYPE_COS, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = cosFunction, + .finalizeFunc = NULL + }, + { + .name = "tan", + .type = FUNCTION_TYPE_TAN, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = tanFunction, + .finalizeFunc = NULL + }, + { + .name = "asin", + .type = FUNCTION_TYPE_ASIN, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = asinFunction, + .finalizeFunc = NULL + }, + { + .name = "acos", + .type = FUNCTION_TYPE_ACOS, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = acosFunction, + .finalizeFunc = NULL + }, + { + .name = "atan", + .type = FUNCTION_TYPE_ATAN, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = stubCheckAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = atanFunction, + .finalizeFunc = NULL + }, { .name = "concat", .type = FUNCTION_TYPE_CONCAT, diff --git a/source/libs/scalar/inc/sclfunc.h b/source/libs/scalar/inc/sclfunc.h index 8e03470033..8915f37261 100644 --- a/source/libs/scalar/inc/sclfunc.h +++ b/source/libs/scalar/inc/sclfunc.h @@ -37,7 +37,6 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarParam* void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t)); - #ifdef __cplusplus } #endif diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 9ae118607e..f2fdb29e4a 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -4,145 +4,536 @@ static void assignBasicParaInfo(struct SScalarParam* dst, const struct SScalarParam* src) { dst->type = src->type; dst->bytes = src->bytes; - dst->num = src->num; + //dst->num = src->num; } -static void tceil(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) { - assignBasicParaInfo(pOutput, pLeft); - assert(numOfInput == 1); - - switch (pLeft->bytes) { - case TSDB_DATA_TYPE_FLOAT: { - float* p = (float*) pLeft->data; - float* out = (float*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = ceilf(p[i]); - } - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* p = (double*) pLeft->data; - double* out = (double*)pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = ceil(p[i]); - } - } - - default: - memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes); +/** Math functions **/ +int32_t absFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + assignBasicParaInfo(pOutput, pInput); + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; } + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + switch (pInput->type) { + case TSDB_DATA_TYPE_FLOAT: { + float v; + GET_TYPED_DATA(v, float, pInput->type, input); + float result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_TINYINT: { + int8_t v; + GET_TYPED_DATA(v, int8_t, pInput->type, input); + int8_t result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + int16_t v; + GET_TYPED_DATA(v, int16_t, pInput->type, input); + int16_t result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_INT: { + int32_t v; + GET_TYPED_DATA(v, int32_t, pInput->type, input); + int32_t result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + int64_t v; + GET_TYPED_DATA(v, int64_t, pInput->type, input); + int64_t result; + result = (v > 0) ? v : -v; + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + default: { + memcpy(output, input, pInput->bytes); + break; + } + } + } + + return TSDB_CODE_SUCCESS; } -static void tfloor(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) { - assignBasicParaInfo(pOutput, pLeft); - assert(numOfInput == 1); - - switch (pLeft->bytes) { - case TSDB_DATA_TYPE_FLOAT: { - float* p = (float*) pLeft->data; - float* out = (float*) pOutput->data; - - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = floorf(p[i]); - } - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* p = (double*) pLeft->data; - double* out = (double*) pOutput->data; - - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = floor(p[i]); - } - } - - default: - memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes); +int32_t logFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 2 || !IS_NUMERIC_TYPE(pInput[0].type) || !IS_NUMERIC_TYPE(pInput[1].type)) { + return TSDB_CODE_FAILED; } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char **input = NULL, *output = NULL; + bool hasNullInput = false; + input = taosMemoryCalloc(inputNum, sizeof(char *)); + for (int32_t i = 0; i < pOutput->num; ++i) { + for (int32_t j = 0; j < inputNum; ++j) { + if (pInput[j].num == 1) { + input[j] = pInput[j].data; + } else { + input[j] = pInput[j].data + i * pInput[j].bytes; + } + if (isNull(input[j], pInput[j].type)) { + hasNullInput = true; + break; + } + } + output = pOutput->data + i * pOutput->bytes; + + if (hasNullInput) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double base; + GET_TYPED_DATA(base, double, pInput[1].type, input[1]); + double v; + GET_TYPED_DATA(v, double, pInput[0].type, input[0]); + double result = log(v) / log(base); + SET_TYPED_DATA(output, pOutput->type, result); + } + + taosMemoryFree(input); + + return TSDB_CODE_SUCCESS; } -static void _tabs(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) { - assignBasicParaInfo(pOutput, pLeft); - assert(numOfInput == 1); - - switch (pLeft->bytes) { - case TSDB_DATA_TYPE_FLOAT: { - float* p = (float*) pLeft->data; - float* out = (float*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* p = (double*) pLeft->data; - double* out = (double*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - case TSDB_DATA_TYPE_TINYINT: { - int8_t* p = (int8_t*) pLeft->data; - int8_t* out = (int8_t*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - case TSDB_DATA_TYPE_SMALLINT: { - int16_t* p = (int16_t*) pLeft->data; - int16_t* out = (int16_t*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - case TSDB_DATA_TYPE_INT: { - int32_t* p = (int32_t*) pLeft->data; - int32_t* out = (int32_t*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - case TSDB_DATA_TYPE_BIGINT: { - int64_t* p = (int64_t*) pLeft->data; - int64_t* out = (int64_t*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = (p[i] > 0)? p[i]:-p[i]; - } - } - - default: - memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes); +int32_t powFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 2 || !IS_NUMERIC_TYPE(pInput[0].type) || !IS_NUMERIC_TYPE(pInput[1].type)) { + return TSDB_CODE_FAILED; } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char **input = NULL, *output = NULL; + bool hasNullInput = false; + input = taosMemoryCalloc(inputNum, sizeof(char *)); + for (int32_t i = 0; i < pOutput->num; ++i) { + for (int32_t j = 0; j < inputNum; ++j) { + if (pInput[j].num == 1) { + input[j] = pInput[j].data; + } else { + input[j] = pInput[j].data + i * pInput[j].bytes; + } + if (isNull(input[j], pInput[j].type)) { + hasNullInput = true; + break; + } + } + output = pOutput->data + i * pOutput->bytes; + + if (hasNullInput) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double base; + GET_TYPED_DATA(base, double, pInput[1].type, input[1]); + double v; + GET_TYPED_DATA(v, double, pInput[0].type, input[0]); + double result = pow(v, base); + SET_TYPED_DATA(output, pOutput->type, result); + } + + taosMemoryFree(input); + + return TSDB_CODE_SUCCESS; } -static void tround(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) { - assignBasicParaInfo(pOutput, pLeft); - assert(numOfInput == 1); - - switch (pLeft->bytes) { - case TSDB_DATA_TYPE_FLOAT: { - float* p = (float*) pLeft->data; - float* out = (float*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = roundf(p[i]); - } - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* p = (double*) pLeft->data; - double* out = (double*) pOutput->data; - for (int32_t i = 0; i < pLeft->num; ++i) { - out[i] = round(p[i]); - } - } - - default: - memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes); +int32_t sqrtFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = sqrt(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t sinFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = sin(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t cosFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = cos(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t tanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = tan(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t asinFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = asin(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t acosFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = acos(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + pOutput->type = TSDB_DATA_TYPE_DOUBLE; + pOutput->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = atan(v); + SET_TYPED_DATA(output, pOutput->type, result); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t ceilFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + switch (pInput->type) { + case TSDB_DATA_TYPE_FLOAT: { + float v; + GET_TYPED_DATA(v, float, pInput->type, input); + float result = ceilf(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = ceil(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + default: { + memcpy(output, input, pInput->bytes); + break; + } + } + } + + return TSDB_CODE_SUCCESS; +} + +int32_t floorFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + assignBasicParaInfo(pOutput, pInput); + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + switch (pInput->type) { + case TSDB_DATA_TYPE_FLOAT: { + float v; + GET_TYPED_DATA(v, float, pInput->type, input); + float result = floorf(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = floor(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + default: { + memcpy(output, input, pInput->bytes); + break; + } + } + } + + return TSDB_CODE_SUCCESS; +} + +int32_t roundFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + assignBasicParaInfo(pOutput, pInput); + if (inputNum != 1 || !IS_NUMERIC_TYPE(pInput->type)) { + return TSDB_CODE_FAILED; + } + + char *input = NULL, *output = NULL; + for (int32_t i = 0; i < pOutput->num; ++i) { + if (pInput->num == 1) { + input = pInput->data; + } else { + input = pInput->data + i * pInput->bytes; + } + output = pOutput->data + i * pOutput->bytes; + + if (isNull(input, pInput->type)) { + setNull(output, pOutput->type, pOutput->bytes); + continue; + } + + switch (pInput->type) { + case TSDB_DATA_TYPE_FLOAT: { + float v; + GET_TYPED_DATA(v, float, pInput->type, input); + float result = roundf(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double v; + GET_TYPED_DATA(v, double, pInput->type, input); + double result = round(v); + SET_TYPED_DATA(output, pOutput->type, result); + break; + } + + default: { + memcpy(output, input, pInput->bytes); + break; + } + } + } + + return TSDB_CODE_SUCCESS; } static void tlength(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) { @@ -361,16 +752,16 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa #endif -SScalarFunctionInfo scalarFunc[8] = { - {"ceil", FUNCTION_TYPE_SCALAR, FUNCTION_CEIL, tceil}, - {"floor", FUNCTION_TYPE_SCALAR, FUNCTION_FLOOR, tfloor}, - {"abs", FUNCTION_TYPE_SCALAR, FUNCTION_ABS, _tabs}, - {"round", FUNCTION_TYPE_SCALAR, FUNCTION_ROUND, tround}, - {"length", FUNCTION_TYPE_SCALAR, FUNCTION_LENGTH, tlength}, - {"concat", FUNCTION_TYPE_SCALAR, FUNCTION_CONCAT, tconcat}, - {"ltrim", FUNCTION_TYPE_SCALAR, FUNCTION_LTRIM, tltrim}, - {"rtrim", FUNCTION_TYPE_SCALAR, FUNCTION_RTRIM, trtrim}, -}; +//SScalarFunctionInfo scalarFunc[8] = { +// {"ceil", FUNCTION_TYPE_SCALAR, FUNCTION_CEIL, tceil}, +// {"floor", FUNCTION_TYPE_SCALAR, FUNCTION_FLOOR, tfloor}, +// {"abs", FUNCTION_TYPE_SCALAR, FUNCTION_ABS, _tabs}, +// {"round", FUNCTION_TYPE_SCALAR, FUNCTION_ROUND, tround}, +// {"length", FUNCTION_TYPE_SCALAR, FUNCTION_LENGTH, tlength}, +// {"concat", FUNCTION_TYPE_SCALAR, FUNCTION_CONCAT, tconcat}, +// {"ltrim", FUNCTION_TYPE_SCALAR, FUNCTION_LTRIM, tltrim}, +// {"rtrim", FUNCTION_TYPE_SCALAR, FUNCTION_RTRIM, trtrim}, +//}; void setScalarFunctionSupp(struct SScalarFunctionSupport* sas, SExprInfo *pExprInfo, SSDataBlock* pSDataBlock) { sas->numOfCols = (int32_t) pSDataBlock->info.numOfCols; @@ -411,4 +802,4 @@ void destroyScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t n } taosMemoryFreeClear(pSupport); -} \ No newline at end of file +} diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp index dfa141d706..f0025de6b8 100644 --- a/source/libs/scalar/test/scalar/scalarTests.cpp +++ b/source/libs/scalar/test/scalar/scalarTests.cpp @@ -39,6 +39,14 @@ #include "nodes.h" #include "tlog.h" +#define _DEBUG_PRINT_ 0 + +#if _DEBUG_PRINT_ +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + namespace { SColumnInfo createColumnInfo(int32_t colId, int32_t type, int32_t bytes) { @@ -1433,6 +1441,1645 @@ TEST(columnTest, greater_and_lower) { nodesDestroyNode(logicNode); } +void scltMakeDataBlock(SScalarParam **pInput, int32_t type, void *pVal, int32_t num, bool setVal) { + SScalarParam *input = (SScalarParam *)taosMemoryCalloc(1, sizeof(SScalarParam)); + int32_t bytes; + switch (type) { + case TSDB_DATA_TYPE_TINYINT: { + bytes = sizeof(int8_t); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + bytes = sizeof(int16_t); + break; + } + case TSDB_DATA_TYPE_INT: { + bytes = sizeof(int32_t); + break; + } + case TSDB_DATA_TYPE_BIGINT: { + bytes = sizeof(int64_t); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + bytes = sizeof(float); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + bytes = sizeof(double); + break; + } + } + + input->type = type; + input->num = num; + input->data = taosMemoryCalloc(num, bytes); + input->bytes = bytes; + if (setVal) { + for (int32_t i = 0; i < num; ++i) { + memcpy(input->data + i * bytes, pVal, bytes); + } + } else { + memset(input->data, 0, num * bytes); + } + + *pInput = input; +} + +void scltDestroyDataBlock(SScalarParam *pInput) { + taosMemoryFree(pInput->data); + taosMemoryFree(pInput); +} + +TEST(ScalarFunctionTest, absFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + + //TINYINT + int8_t val_tinyint = 10; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), val_tinyint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_tinyint = -10; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), -val_tinyint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //SMALLINT + int16_t val_smallint = 10; + type = TSDB_DATA_TYPE_SMALLINT; + scltMakeDataBlock(&pInput, type, &val_smallint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int16_t *)pOutput->data + i), val_smallint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_smallint = -10; + scltMakeDataBlock(&pInput, type, &val_smallint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int16_t *)pOutput->data + i), -val_smallint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //INT + int32_t val_int = 10; + type = TSDB_DATA_TYPE_INT; + scltMakeDataBlock(&pInput, type, &val_int, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int32_t *)pOutput->data + i), val_int); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_int = -10; + scltMakeDataBlock(&pInput, type, &val_int, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int32_t *)pOutput->data + i), -val_int); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //BIGINT + int64_t val_bigint = 10; + type = TSDB_DATA_TYPE_BIGINT; + scltMakeDataBlock(&pInput, type, &val_bigint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int64_t *)pOutput->data + i), val_bigint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_bigint = -10; + scltMakeDataBlock(&pInput, type, &val_bigint, rowNum, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int64_t *)pOutput->data + i), -val_bigint); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 10.15; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("float before ABS:%f\n", *(float *)pInput->data); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), val_float); + PRINTF("float after ABS:%f\n", *((float *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_float = -10.15; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("float before ABS:%f\n", *(float *)pInput->data); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), -val_float); + PRINTF("float after ABS:%f\n", *((float *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //DOUBLE + double val_double = 10.15; + type = TSDB_DATA_TYPE_DOUBLE; + scltMakeDataBlock(&pInput, type, &val_double, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), val_double); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_double = -10.15; + scltMakeDataBlock(&pInput, type, &val_double, rowNum, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), -val_double); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + +} + +TEST(ScalarFunctionTest, absFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 5; + int32_t type; + + //TINYINT + int8_t val_tinyint = 10; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint + i; + PRINTF("tiny_int before ABS:%d\n", *((int8_t *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), val_tinyint + i); + PRINTF("tiny_int after ABS:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_tinyint = -10; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint + i; + PRINTF("tiny_int before ABS:%d\n", *((int8_t *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), -(val_tinyint + i)); + PRINTF("tiny_int after ABS:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //SMALLINT + int16_t val_smallint = 10; + type = TSDB_DATA_TYPE_SMALLINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int16_t *)pInput->data + i) = val_smallint + i; + PRINTF("small_int before ABS:%d\n", *((int16_t *)pInput->data + i)); + } + + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int16_t *)pOutput->data + i), val_smallint + i); + PRINTF("small_int after ABS:%d\n", *((int16_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_smallint = -10; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int16_t *)pInput->data + i) = val_smallint + i; + PRINTF("small_int before ABS:%d\n", *((int16_t *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int16_t *)pOutput->data + i), -(val_smallint + i)); + PRINTF("small_int after ABS:%d\n", *((int16_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //INT + int32_t val_int = 10; + type = TSDB_DATA_TYPE_INT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int32_t *)pInput->data + i) = val_int + i; + PRINTF("int before ABS:%d\n", *((int32_t *)pInput->data + i)); + } + + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int32_t *)pOutput->data + i), val_int + i); + PRINTF("int after ABS:%d\n", *((int32_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_int = -10; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int32_t *)pInput->data + i) = val_int + i; + PRINTF("int before ABS:%d\n", *((int32_t *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int32_t *)pOutput->data + i), -(val_int + i)); + PRINTF("int after ABS:%d\n", *((int32_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 10.15; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float + i; + PRINTF("float before ABS:%f\n", *((float *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), val_float + i); + PRINTF("float after ABS:%f\n", *((float *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_float = -10.15; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float + i; + PRINTF("float before ABS:%f\n", *((float *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), -(val_float + i)); + PRINTF("float after ABS:%f\n", *((float *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //DOUBLE + double val_double = 10.15; + type = TSDB_DATA_TYPE_DOUBLE; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((double *)pInput->data + i) = val_double + i; + PRINTF("double before ABS:%f\n", *((double *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), val_double + i); + PRINTF("double after ABS:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + val_double = -10.15; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((double *)pInput->data + i) = val_double + i; + PRINTF("double before ABS:%f\n", *((double *)pInput->data + i)); + } + + code = absFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), -(val_double + i)); + PRINTF("double after ABS:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, sinFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 0.42016703682664092; + + //TINYINT + int8_t val_tinyint = 13; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before SIN:%d\n", *((int8_t *)pInput->data)); + + code = sinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after SIN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 13.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before SIN:%f\n", *((float *)pInput->data)); + + code = sinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after SIN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + +} + +TEST(ScalarFunctionTest, sinFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {0.42016703682664092, 0.99060735569487035, 0.65028784015711683}; + + + //TINYINT + int8_t val_tinyint[] = {13, 14, 15}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before SIN:%d\n", *((int8_t *)pInput->data + i)); + } + + code = sinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after SIN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {13.00, 14.00, 15.00}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before SIN:%f\n", *((float *)pInput->data + i)); + } + + code = sinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after SIN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, cosFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 0.90744678145019619; + + //TINYINT + int8_t val_tinyint = 13; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before COS:%d\n", *((int8_t *)pInput->data)); + + code = cosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after COS:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 13.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before COS:%f\n", *((float *)pInput->data)); + + code = cosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after COS:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, cosFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {0.90744678145019619, 0.13673721820783361, -0.75968791285882131}; + + //TINYINT + int8_t val_tinyint[] = {13, 14, 15}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before COS:%d\n", *((int8_t *)pInput->data + i)); + } + + code = cosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after COS:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {13.00, 14.00, 15.00}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before COS:%f\n", *((float *)pInput->data + i)); + } + + code = cosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after COS:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, tanFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 0.46302113293648961; + + //TINYINT + int8_t val_tinyint = 13; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before TAN:%d\n", *((int8_t *)pInput->data)); + + code = tanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after TAN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 13.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before TAN:%f\n", *((float *)pInput->data)); + + code = tanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after TAN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, tanFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {0.46302113293648961, 7.24460661609480550, -0.85599340090851872}; + + //TINYINT + int8_t val_tinyint[] = {13, 14, 15}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before TAN:%d\n", *((int8_t *)pInput->data + i)); + } + + code = tanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after TAN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {13.00, 14.00, 15.00}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before TAN:%f\n", *((float *)pInput->data + i)); + } + + code = tanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after TAN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, asinFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 1.57079632679489656; + + //TINYINT + int8_t val_tinyint = 1; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before ASIN:%d\n", *((int8_t *)pInput->data)); + + code = asinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after ASIN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 1.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before ASIN:%f\n", *((float *)pInput->data)); + + code = asinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after ASIN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, asinFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {-1.57079632679489656, 0.0, 1.57079632679489656}; + + + //TINYINT + int8_t val_tinyint[] = {-1, 0, 1}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before ASIN:%d\n", *((int8_t *)pInput->data + i)); + } + + code = asinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after ASIN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-1.0, 0.0, 1.0}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before ASIN:%f\n", *((float *)pInput->data + i)); + } + + code = asinFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after ASIN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, acosFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 0.0; + + //TINYINT + int8_t val_tinyint = 1; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before ACOS:%d\n", *((int8_t *)pInput->data)); + + code = acosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after ACOS:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 1.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before ACOS:%f\n", *((float *)pInput->data)); + + code = acosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after ACOS:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, acosFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {3.14159265358979312, 1.57079632679489656, 0.0}; + + //TINYINT + int8_t val_tinyint[] = {-1, 0, 1}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before ACOS:%d\n", *((int8_t *)pInput->data + i)); + } + + code = acosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after ACOS:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-1.0, 0.0, 1.0}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before ACOS:%f\n", *((float *)pInput->data + i)); + } + + code = acosFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after ACOS:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, atanFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 0.78539816339744828; + + //TINYINT + int8_t val_tinyint = 1; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before ATAN:%d\n", *((int8_t *)pInput->data)); + + code = atanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after ATAN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 1.00; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before ATAN:%f\n", *((float *)pInput->data)); + + code = atanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after ATAN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, atanFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {-0.78539816339744828, 0.0, 0.78539816339744828}; + + //TINYINT + int8_t val_tinyint[] = {-1, 0, 1}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before ATAN:%d\n", *((int8_t *)pInput->data + i)); + } + + code = atanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after ATAN:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-1.0, 0.0, 1.0}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before ATAN:%f\n", *((float *)pInput->data + i)); + } + + code = atanFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after ATAN:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, ceilFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result = 10.0; + + //TINYINT + int8_t val_tinyint = 10; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("tiny_int before CEIL:%d\n", *((int8_t *)pInput->data)); + + code = ceilFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), (int8_t)result); + PRINTF("tiny_int after CEIL:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 9.5; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("float before CEIL:%f\n", *((float *)pInput->data)); + + code = ceilFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), (float)result); + PRINTF("float after CEIL:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, ceilFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result[] = {-10.0, 0.0, 10.0}; + + //TINYINT + int8_t val_tinyint[] = {-10, 0, 10}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before CEIL:%d\n", *((int8_t *)pInput->data + i)); + } + + code = ceilFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), result[i]); + PRINTF("tiny_int after CEIL:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-10.5, 0.0, 9.5}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before CEIL:%f\n", *((float *)pInput->data + i)); + } + + code = ceilFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), result[i]); + PRINTF("float after CEIL:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, floorFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result = 10.0; + + //TINYINT + int8_t val_tinyint = 10; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("tiny_int before FLOOR:%d\n", *((int8_t *)pInput->data)); + + code = floorFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), (int8_t)result); + PRINTF("tiny_int after FLOOR:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 10.5; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("float before FLOOR:%f\n", *((float *)pInput->data)); + + code = floorFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), (float)result); + PRINTF("float after FLOOR:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, floorFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result[] = {-10.0, 0.0, 10.0}; + + //TINYINT + int8_t val_tinyint[] = {-10, 0, 10}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before FLOOR:%d\n", *((int8_t *)pInput->data + i)); + } + + code = floorFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), result[i]); + PRINTF("tiny_int after FLOOR:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-9.5, 0.0, 10.5}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before FLOOR:%f\n", *((float *)pInput->data + i)); + } + + code = floorFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), result[i]); + PRINTF("float after FLOOR:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, roundFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result = 10.0; + + //TINYINT + int8_t val_tinyint = 10; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("tiny_int before ROUND:%d\n", *((int8_t *)pInput->data)); + + code = roundFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), (int8_t)result); + PRINTF("tiny_int after ROUND:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 9.5; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + PRINTF("float before ROUND:%f\n", *((float *)pInput->data)); + + code = roundFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), (float)result); + PRINTF("float after ROUND:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, roundFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + double result[] = {-10.0, 0.0, 10.0}; + + //TINYINT + int8_t val_tinyint[] = {-10, 0, 10}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before ROUND:%d\n", *((int8_t *)pInput->data + i)); + } + + code = roundFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((int8_t *)pOutput->data + i), result[i]); + PRINTF("tiny_int after ROUND:%d\n", *((int8_t *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {-9.5, 0.0, 9.5}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, type, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before ROUND:%f\n", *((float *)pInput->data + i)); + } + + code = roundFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((float *)pOutput->data + i), result[i]); + PRINTF("float after ROUND:%f\n", *((float *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, sqrtFunction_constant) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 5.0; + + //TINYINT + int8_t val_tinyint = 25; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, &val_tinyint, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before SQRT:%d\n", *((int8_t *)pInput->data)); + + code = sqrtFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after SQRT:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float = 25.0; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, &val_float, 1, true); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before SQRT:%f\n", *((float *)pInput->data)); + + code = sqrtFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after SQRT:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, sqrtFunction_column) { + SScalarParam *pInput, *pOutput; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {5.0, 9.0, 10.0}; + + //TINYINT + int8_t val_tinyint[] = {25, 81, 100}; + type = TSDB_DATA_TYPE_TINYINT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput->data + i) = val_tinyint[i]; + PRINTF("tiny_int before SQRT:%d\n", *((int8_t *)pInput->data + i)); + } + + code = sqrtFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after SQRT:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {25.0, 81.0, 100.0}; + type = TSDB_DATA_TYPE_FLOAT; + scltMakeDataBlock(&pInput, type, 0, rowNum, false); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput->data + i) = val_float[i]; + PRINTF("float before SQRT:%f\n", *((float *)pInput->data + i)); + } + + code = sqrtFunction(pInput, 1, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after SQRT:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(pInput); + scltDestroyDataBlock(pOutput); +} + +TEST(ScalarFunctionTest, logFunction_constant) { + SScalarParam *pInput, *pOutput; + SScalarParam *input[2]; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 3.0; + pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam)); + + //TINYINT + int8_t val_tinyint[] = {27, 3}; + type = TSDB_DATA_TYPE_TINYINT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, &val_tinyint[i], 1, true); + pInput[i] = *input[i]; + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before LOG: %d,%d\n", *((int8_t *)pInput[0].data), + *((int8_t *)pInput[1].data)); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after LOG:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {64.0, 4.0}; + type = TSDB_DATA_TYPE_FLOAT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, &val_float[i], 1, true); + pInput[i] = *input[i]; + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before LOG: %f,%f\n", *((float *)pInput[0].data), + *((float *)pInput[1].data)); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after LOG:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //TINYINT AND FLOAT + int8_t param0 = 64; + float param1 = 4.0; + scltMakeDataBlock(&input[0], TSDB_DATA_TYPE_TINYINT, ¶m0, 1, true); + pInput[0] = *input[0]; + scltMakeDataBlock(&input[1], TSDB_DATA_TYPE_FLOAT, ¶m1, 1, true); + pInput[1] = *input[1]; + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + PRINTF("tiny_int,float before LOG: %d,%f\n", *((int8_t *)pInput[0].data), *((float *)pInput[1].data)); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int,float after LOG:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + taosMemoryFree(pInput); +} + +TEST(ScalarFunctionTest, logFunction_column) { + SScalarParam *pInput, *pOutput; + SScalarParam *input[2]; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {2.0, 4.0, 3.0}; + pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam)); + + //TINYINT + int8_t val_tinyint[2][3] = {{25, 81, 64}, {5, 3, 4}}; + type = TSDB_DATA_TYPE_TINYINT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, 0, rowNum, false); + pInput[i] = *input[i]; + for (int32_t j = 0; j < rowNum; ++j) { + *((int8_t *)pInput[i].data + j) = val_tinyint[i][j]; + } + PRINTF("tiny_int before LOG:%d,%d,%d\n", *((int8_t *)pInput[i].data + 0), + *((int8_t *)pInput[i].data + 1), + *((int8_t *)pInput[i].data + 2)); + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after LOG:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[2][3] = {{25.0, 81.0, 64.0}, {5.0, 3.0, 4.0}}; + type = TSDB_DATA_TYPE_FLOAT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, 0, rowNum, false); + pInput[i] = *input[i]; + for (int32_t j = 0; j < rowNum; ++j) { + *((float *)pInput[i].data + j) = val_float[i][j]; + } + PRINTF("float before LOG:%f,%f,%f\n", *((float *)pInput[i].data + 0), + *((float *)pInput[i].data + 1), + *((float *)pInput[i].data + 2)); + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after LOG:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //TINYINT AND FLOAT + int8_t param0[] = {25, 81, 64}; + float param1[] = {5.0, 3.0, 4.0}; + scltMakeDataBlock(&input[0], TSDB_DATA_TYPE_TINYINT, 0, rowNum, false); + pInput[0] = *input[0]; + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput[0].data + i) = param0[i]; + } + scltMakeDataBlock(&input[1], TSDB_DATA_TYPE_FLOAT, 0, rowNum, false); + pInput[1] = *input[1]; + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput[1].data + i) = param1[i]; + } + PRINTF("tiny_int, float before LOG:{%d,%f}, {%d,%f}, {%d,%f}\n", *((int8_t *)pInput[0].data + 0), *((float *)pInput[1].data + 0), + *((int8_t *)pInput[0].data + 1), *((float *)pInput[1].data + 1), + *((int8_t *)pInput[0].data + 2), *((float *)pInput[1].data + 2)); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = logFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int,float after LOG:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + taosMemoryFree(pInput); +} + +TEST(ScalarFunctionTest, powFunction_constant) { + SScalarParam *pInput, *pOutput; + SScalarParam *input[2]; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result = 16.0; + pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam)); + + //TINYINT + int8_t val_tinyint[] = {2, 4}; + type = TSDB_DATA_TYPE_TINYINT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, &val_tinyint[i], 1, true); + pInput[i] = *input[i]; + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("tiny_int before POW: %d,%d\n", *((int8_t *)pInput[0].data), + *((int8_t *)pInput[1].data)); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int after POW:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[] = {2.0, 4.0}; + type = TSDB_DATA_TYPE_FLOAT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, &val_float[i], 1, true); + pInput[i] = *input[i]; + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + PRINTF("float before POW: %f,%f\n", *((float *)pInput[0].data), + *((float *)pInput[1].data)); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("float after POW:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //TINYINT AND FLOAT + int8_t param0 = 2; + float param1 = 4.0; + scltMakeDataBlock(&input[0], TSDB_DATA_TYPE_TINYINT, ¶m0, 1, true); + pInput[0] = *input[0]; + scltMakeDataBlock(&input[1], TSDB_DATA_TYPE_FLOAT, ¶m1, 1, true); + pInput[1] = *input[1]; + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + PRINTF("tiny_int,float before POW: %d,%f\n", *((int8_t *)pInput[0].data), *((float *)pInput[1].data)); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result); + PRINTF("tiny_int,float after POW:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + taosMemoryFree(pInput); +} + +TEST(ScalarFunctionTest, powFunction_column) { + SScalarParam *pInput, *pOutput; + SScalarParam *input[2]; + int32_t code = TSDB_CODE_SUCCESS; + int32_t rowNum = 3; + int32_t type; + int32_t otype = TSDB_DATA_TYPE_DOUBLE; + double result[] = {32.0, 27.0, 16.0}; + pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam)); + + //TINYINT + int8_t val_tinyint[2][3] = {{2, 3, 4}, {5, 3, 2}}; + type = TSDB_DATA_TYPE_TINYINT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, 0, rowNum, false); + pInput[i] = *input[i]; + for (int32_t j = 0; j < rowNum; ++j) { + *((int8_t *)pInput[i].data + j) = val_tinyint[i][j]; + } + PRINTF("tiny_int before POW:%d,%d,%d\n", *((int8_t *)pInput[i].data + 0), + *((int8_t *)pInput[i].data + 1), + *((int8_t *)pInput[i].data + 2)); + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int after POW:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //FLOAT + float val_float[2][3] = {{2.0, 3.0, 4.0}, {5.0, 3.0, 2.0}}; + type = TSDB_DATA_TYPE_FLOAT; + for (int32_t i = 0; i < 2; ++i) { + scltMakeDataBlock(&input[i], type, 0, rowNum, false); + pInput[i] = *input[i]; + for (int32_t j = 0; j < rowNum; ++j) { + *((float *)pInput[i].data + j) = val_float[i][j]; + } + PRINTF("float before POW:%f,%f,%f\n", *((float *)pInput[i].data + 0), + *((float *)pInput[i].data + 1), + *((float *)pInput[i].data + 2)); + } + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("float after POW:%f\n", *((double *)pOutput->data + i)); + } + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + + //TINYINT AND FLOAT + int8_t param0[] = {2, 3, 4}; + float param1[] = {5.0, 3.0, 2.0}; + scltMakeDataBlock(&input[0], TSDB_DATA_TYPE_TINYINT, 0, rowNum, false); + pInput[0] = *input[0]; + for (int32_t i = 0; i < rowNum; ++i) { + *((int8_t *)pInput[0].data + i) = param0[i]; + } + scltMakeDataBlock(&input[1], TSDB_DATA_TYPE_FLOAT, 0, rowNum, false); + pInput[1] = *input[1]; + for (int32_t i = 0; i < rowNum; ++i) { + *((float *)pInput[1].data + i) = param1[i]; + } + PRINTF("tiny_int, float before POW:{%d,%f}, {%d,%f}, {%d,%f}\n", *((int8_t *)pInput[0].data + 0), *((float *)pInput[1].data + 0), + *((int8_t *)pInput[0].data + 1), *((float *)pInput[1].data + 1), + *((int8_t *)pInput[0].data + 2), *((float *)pInput[1].data + 2)); + scltMakeDataBlock(&pOutput, otype, 0, rowNum, false); + + code = powFunction(pInput, 2, pOutput); + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + for (int32_t i = 0; i < rowNum; ++i) { + ASSERT_EQ(*((double *)pOutput->data + i), result[i]); + PRINTF("tiny_int,float after POW:%f\n", *((double *)pOutput->data + i)); + } + + scltDestroyDataBlock(input[0]); + scltDestroyDataBlock(input[1]); + scltDestroyDataBlock(pOutput); + taosMemoryFree(pInput); +} int main(int argc, char** argv) { taosSeedRand(taosGetTimestampSec());