大家一直想要的自定义函数,这次终于来啦,虽然目前还有点简单,不过 CH 的功能进一步丰富了。
这几天发现,一直有关注的自定义simple lambda function 这个 feature 被合并到主线了,那还不赶紧试一试?(文末会放上PR地址)
自定义 lambda 函数的语法如下:
代码语言:javascript复制CREATE FUNCTION {fn_name} as ({parameters}) -> {code}
例如创建一个自定义函数 testFunc:
代码语言:javascript复制CREATE FUNCTION testFunc AS (a, b) -> (a b)
Query id: da558806-259f-428b-b777-5ecbbea8bae1
Ok.
0 rows in set. Elapsed: 0.004 sec.
创建之后,就可以在查询中使用了:
代码语言:javascript复制SELECT testFunc(1, 2)
Query id: 9fba3a87-e577-44ae-bfe2-332c587aa180
┌─plus(1, 2)─┐
│ 3 │
└────────────┘
1 rows in set. Elapsed: 0.003 sec.
让我们来一点复杂的情况:
代码语言:javascript复制CREATE FUNCTION testFunc1 AS (a, b, c) -> a b > c AND c < 20
验证结果:
代码语言:javascript复制SELECT
testFunc1(5, 6, 1),
testFunc1(5, 6, 19),
testFunc1(20, 40, 30)
Query id: 17cfe0a7-681f-4b28-81fa-718fe38f8a2a
┌─and(greater(plus(5, 6), 1), less(1, 20))─┬─and(greater(plus(5, 6), 19), less(19, 20))─┬─and(greater(plus(20, 40), 30), less(30, 20))─┐
│ 1 │ 0 │ 0 │
└──────────────────────────────────────────┴────────────────────────────────────────────┴──────────────────────────────────────────────┘
1 rows in set. Elapsed: 0.003 sec.
在自定义函数中,尝试调用系统函数:
代码语言:javascript复制create function createInfo as (perfix,state) -> multiIf(state==0,concat(perfix,'未开始'),state>0 and state<1 ,concat(perfix,'进行中'),state>=1 ,concat(perfix,'已完成'),'未知状态')
查询是OK的,但是好像列名没有办法设置别名:
代码语言:javascript复制SELECT create_info('任务', 0) AS n1
Query id: 46c12694-3335-4d0b-8d55-e60802c68d2e
┌─multiIf(equals(0, 0), concat('任务', '未开始'), and(greater(0, 0), less(0, 1)), concat('任务', '进行中'), greaterOrEquals(0, 1), concat('任务', '已完成'), '未知状态')─┐
│ 任务未开始 │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
1 rows in set. Elapsed: 0.003 sec.
直接使用表字段也没有问题:
代码语言:javascript复制SELECT
testFunc(JavaEnable, GoodEvent),
JavaEnable,
GoodEvent
FROM hits_100m_obfuscated
LIMIT 5
Query id: 30e05cdd-da21-46db-8a11-49c5fb348668
┌─plus(JavaEnable, GoodEvent)─┬─JavaEnable─┬─GoodEvent─┐
│ 1 │ 0 │ 1 │
│ 1 │ 0 │ 1 │
│ 1 │ 0 │ 1 │
│ 1 │ 0 │ 1 │
│ 1 │ 0 │ 1 │
└─────────────────────────────┴────────────┴───────────┘
5 rows in set. Elapsed: 0.006 sec.
进到 ClickHouse 的存储目录,会发现多了一个 user_defined 目录,专门用于保存 UDF 的元数据:
代码语言:javascript复制% data/user_defined % ls -l
total 16
-rw-r----- 1 nauu staff 46 9 18 08:00 function_testFunc.sql
-rw-r----- 1 nauu staff 71 9 18 08:03 function_testFunc1.sql
代码语言:javascript复制% cat ./function_testFunc.sql
CREATE FUNCTION testFunc AS (a, b) -> (a b)
我们也可以使用 Drop Function 删除 UDF:
代码语言:javascript复制DROP FUNCTION testFunc1
Query id: 41b61849-a186-47b9-8072-c4af18be6bab
Ok.
0 rows in set. Elapsed: 0.006 sec.
自定义的函数也会被添加到系统表:
代码语言:javascript复制SELECT *
FROM system.functions
WHERE name = 'testFunc'
Query id: 97037df5-cda6-471f-933f-278670f3b113
┌─name─────┬─is_aggregate─┬─case_insensitive─┬─alias_to─┬─create_query──────────────────────────────────┐
│ testFunc │ 0 │ 0 │ │ CREATE FUNCTION testFunc AS (a, b) -> (a b) │
└──────────┴──────────────┴──────────────────┴──────────┴───────────────────────────────────────────────┘
1 rows in set. Elapsed: 0.003 sec. Processed 1.06 thousand rows, 46.30 KB (304.53 thousand rows/s., 13.24 MB/s.)
好了,今天就分享到这里吧,PR在此:
https://github.com/ClickHouse/ClickHouse/pull/23978
原创不易,如果这篇文章对你有帮助,欢迎 点赞、转发、在看 三连击