Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
4a02684b
T
TDengine
项目概览
taosdata
/
TDengine
11 个月 前同步成功
通知
1179
Star
22014
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4a02684b
编写于
3月 26, 2022
作者:
G
Ganlin Zhao
提交者:
GitHub
3月 26, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #11009 from taosdata/3.0_glzhao_math_func
[TD-14240]<feature>: add math functions
上级
6a773532
8a2623e9
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
2297 addition
and
113 deletion
+2297
-113
include/libs/function/functionMgt.h
include/libs/function/functionMgt.h
+8
-7
include/libs/scalar/scalar.h
include/libs/scalar/scalar.h
+15
-0
source/libs/function/CMakeLists.txt
source/libs/function/CMakeLists.txt
+1
-1
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+131
-0
source/libs/scalar/inc/sclfunc.h
source/libs/scalar/inc/sclfunc.h
+0
-1
source/libs/scalar/src/sclfunc.c
source/libs/scalar/src/sclfunc.c
+495
-104
source/libs/scalar/test/scalar/scalarTests.cpp
source/libs/scalar/test/scalar/scalarTests.cpp
+1647
-0
未找到文件。
include/libs/function/functionMgt.h
浏览文件 @
4a02684b
...
...
@@ -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_SQRT
,
FUNCTION_TYPE_CEIL
,
FUNCTION_TYPE_FLOOR
,
FUNCTION_TYPE_ROUND
,
FUNCTION_TYPE_SIN
,
FUNCTION_TYPE_
SQRT
,
FUNCTION_TYPE_
COS
,
FUNCTION_TYPE_TAN
,
FUNCTION_TYPE_ASIN
,
FUNCTION_TYPE_ACOS
,
FUNCTION_TYPE_ATAN
,
// string function
FUNCTION_TYPE_CHAR_LENGTH
=
1500
,
...
...
include/libs/scalar/scalar.h
浏览文件 @
4a02684b
...
...
@@ -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
}
...
...
source/libs/function/CMakeLists.txt
浏览文件 @
4a02684b
...
...
@@ -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
)
...
...
source/libs/function/src/builtins.c
浏览文件 @
4a02684b
...
...
@@ -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
,
...
...
source/libs/scalar/inc/sclfunc.h
浏览文件 @
4a02684b
...
...
@@ -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
...
...
source/libs/scalar/src/sclfunc.c
浏览文件 @
4a02684b
...
...
@@ -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
);
/** 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
;
}
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
]);
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
;
}
}
}
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
]);
return
TSDB_CODE_SUCCESS
;
}
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
;
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
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
);
}
}
static
void
tfloor
(
SScalarParam
*
pOutput
,
size_t
numOfInput
,
const
SScalarParam
*
pLeft
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
assert
(
numOfInput
==
1
);
taosMemoryFree
(
input
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
return
TSDB_CODE_SUCCESS
;
}
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
;
}
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floorf
(
p
[
i
]);
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
;
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
if
(
hasNullInput
)
{
setNull
(
output
,
pOutput
->
type
,
pOutput
->
bytes
);
continue
;
}
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floor
(
p
[
i
]);
}
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
;
}
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
;
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
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
;
}
static
void
_tabs
(
SScalarParam
*
pOutput
,
size_t
numOfInput
,
const
SScalarParam
*
pLeft
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
assert
(
numOfInput
==
1
);
int32_t
sinFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
)
{
if
(
inputNum
!=
1
||
!
IS_NUMERIC_TYPE
(
pInput
->
type
))
{
return
TSDB_CODE_FAILED
;
}
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
];
}
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
;
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
];
}
if
(
isNull
(
input
,
pInput
->
type
))
{
setNull
(
output
,
pOutput
->
type
,
pOutput
->
bytes
);
continue
;
}
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
];
}
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
;
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
];
}
if
(
isNull
(
input
,
pInput
->
type
))
{
setNull
(
output
,
pOutput
->
type
,
pOutput
->
bytes
);
continue
;
}
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
];
}
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
;
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
];
}
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
;
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
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
;
}
static
void
tround
(
SScalarParam
*
pOutput
,
size_t
numOfInput
,
const
SScalarParam
*
pLeft
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
assert
(
numOfInput
==
1
);
int32_t
acosFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
)
{
if
(
inputNum
!=
1
||
!
IS_NUMERIC_TYPE
(
pInput
->
type
))
{
return
TSDB_CODE_FAILED
;
}
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
]);
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
;
}
}
}
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
]);
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
;
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
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
}
source/libs/scalar/test/scalar/scalarTests.cpp
浏览文件 @
4a02684b
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录