[TD-14240]<feature>: add math functions
This commit is contained in:
parent
1ad4440b56
commit
79002a6e3d
|
@ -36,7 +36,21 @@ extern struct SScalarFunctionInfo scalarFunc[8];
|
|||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarParam* pOutput,
|
||||
void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t));
|
||||
|
||||
int32_t abs_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t log_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t pow_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t sqrt_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
||||
int32_t sin_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t cos_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t tan_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t asin_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t acos_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t atan_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
||||
int32_t ceil_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t floor_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t round_function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -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 abs_function(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 log_function(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 = calloc(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);
|
||||
}
|
||||
|
||||
free(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 pow_function(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 = calloc(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);
|
||||
}
|
||||
|
||||
free(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 sqrt_function(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 sin_function(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 cos_function(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 tan_function(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 asin_function(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 acos_function(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 atan_function(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 ceil_function(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 floor_function(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 round_function(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
|
|||
}
|
||||
|
||||
tfree(pSupport);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue