一、用戶通過SQL創建函數
從 lambda 表達式創建用戶定義的函數。表達式必須由函數參數、常量、運算符或其他函數調用組成。
句法:
CREATE FUNCTION name AS (parameter0, ...) -> expression
--刪除函數 DROP FUNCTION [IF EXISTS] function_name
一個函數可以有任意數量的參數。
有一些限制:
1)函數的名稱在用戶定義函數和系統函數中必須是唯一的。
2)不允許使用遞歸函數。
3)函數使用的所有變量都必須在其參數列表中指定。
如果違反任何限制,則會引發異常。
例子:
CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b; SELECT number, linear_equation(number, 2, 1) FROM numbers(3);
結果:
┌─number─┬─plus(multiply(2, number), 1)─┐ │ 0 │ 1 │ │ 1 │ 3 │ │ 2 │ 5 │ └────────┴──────────────────────────────┘
在以下查詢中的用戶定義函數中調用條件函數:
CREATE FUNCTION parity_str AS (n) -> if(n % 2, 'odd', 'even'); SELECT number, parity_str(number) FROM numbers(3);
結果:
┌─number─┬─if(modulo(number, 2), 'odd', 'even')─┐ │ 0 │ even │ │ 1 │ odd │ │ 2 │ even │ └────────┴──────────────────────────────────────┘
示例
CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b; SELECT number, linear_equation(number, 2, 1) FROM numbers(3); SELECT number, linear_equation(number, 2, 1) FROM numbers(3) Query id: 9a4a2978-b186-4bc2-ac0c-86daf0328212 ┌─number─┬─plus(multiply(2, number), 1)─┐ │ 0 │ 1 │ │ 1 │ 3 │ │ 2 │ 5 │ └────────┴──────────────────────────────┘ 3 rows in set. Elapsed: 0.002 sec. CREATE FUNCTION parity_str AS (n) -> if(n % 2, 'odd', 'even'); SELECT number, parity_str(number) FROM numbers(3); SELECT number, parity_str(number) FROM numbers(3) Query id: 59a97a32-15c4-4417-8444-51cb00a01ac0 ┌─number─┬─if(modulo(number, 2), 'odd', 'even')─┐ │ 0 │ even │ │ 1 │ odd │ │ 2 │ even │ └────────┴──────────────────────────────────────┘ 3 rows in set. Elapsed: 0.002 sec.
二、用戶通過配置文件定義函數
ClickHouse 可以調用任何外部可執行程序或腳本來處理數據。在配置文件中描述這些功能,並將該文件的路徑添加到user_defined_executable_functions_config
設置中的主要配置中。如果路徑中使用了通配符*
,則加載與該模式匹配的所有文件。例子:
<user_defined_executable_functions_config>*_function.xml</user_defined_executable_functions_config>
相對於設置中指定的路徑搜索用戶定義的功能配置user_files_path
。
功能配置包含以下設置:
1)name
- 函數名稱。
2)command
execute_direct
- 如果為假,則執行或命令的腳本名稱。
3)argument
- 帶有type
, 和可選參數的參數描述name
。每個參數都在單獨的設置中進行描述。如果參數名稱是用戶定義的函數格式(如Native或JSONEachRow )的序列化的一部分,則必須指定名稱。默認參數名稱值為c
+ argument_number。
4)format
-將參數傳遞給命令的格式。
5)return_type
- 返回值的類型。
6)return_name
- 返回值的名稱。如果返回名稱是用戶定義函數格式(如Native或JSONEachRow)的序列化的一部分,則需要指定返回名稱。可選的。默認值為result
。
7)type
- 可執行類型。如果type
設置為executable
則啟動單個命令。如果設置為executable_pool
,則創建命令池。
8)max_command_execution_time
- 處理數據塊的最大執行時間(以秒為單位)。此設置僅對executable_pool
命令有效。可選的。默認值為10
。
9)command_termination_timeout
- 關閉管道后命令應該完成的時間(以秒為單位)。之后時間SIGTERM
被發送到執行命令的進程。可選的。默認值為10
。
10)command_read_timeout
- 從命令 stdout 讀取數據的超時時間(以毫秒為單位)。默認值 10000。可選參數。
11)command_write_timeout
- 以毫秒為單位將數據寫入命令標准輸入的超時。默認值 10000。可選參數。
12)pool_size
- 命令池的大小。可選的。默認值為16
。
13)send_chunk_header
- 控制是否在發送要處理的數據塊之前發送行數。可選的。默認值為false
。
14)execute_direct
- 如果execute_direct
= 1
,則將command
在 user_scripts 文件夾中搜索。可以使用空格分隔符指定其他腳本參數。示例:script_name arg1 arg2
。如果execute_direct
= 0
,command
作為 的參數傳遞bin/sh -c
。默認值為1
。可選參數。
15)lifetime
- 以秒為單位的函數的重新加載間隔。如果設置為,0
則不會重新加載該函數。默認值為0
。可選參數。
該命令必須從中讀取參數STDIN
並將結果輸出到STDOUT
. 該命令必須迭代地處理參數。也就是說,在處理了一大塊參數之后,它必須等待下一個塊。
示例test_function
使用 XML 配置 創建。文件 test_function.xml(默認execute_direct
= 1的情況下
)。
<functions> <function> <type>executable</type> <name>test_function_python</name> <return_type>String</return_type> <argument> <type>UInt64</type> <name>value</name> </argument> <format>TabSeparated</format> <command>test_function.py</command> </function> </functions>
user_scripts
文件夾內的腳本文件test_function.py
。
#!/usr/bin/python3 import sys if __name__ == '__main__': for line in sys.stdin: print("Value " + line, end='') sys.stdout.flush()
查詢:
SELECT test_function_python(toUInt64(2));
結果:
┌─test_function_python(2)─┐ │ Value 2 │ └─────────────────────────┘
test_function_sum
手動創建指定execute_direct=0
使用XML 配置。文件 test_function.xml。
<functions> <function> <type>executable</type> <name>test_function_sum</name> <return_type>UInt64</return_type> <argument> <type>UInt64</type> <name>lhs</name> </argument> <argument> <type>UInt64</type> <name>rhs</name> </argument> <format>TabSeparated</format> <command>cd /; clickhouse-local --input-format TabSeparated --output-format TabSeparated --structure 'x UInt64, y UInt64' --query "SELECT x + y FROM table"</command> <execute_direct>0</execute_direct> </function> </functions>
查詢:
SELECT test_function_sum(2, 2);
結果:
┌─test_function_sum(2, 2)─┐ │ 4 │ └─────────────────────────┘
使用 XML 配置使用test_function_sum_json
命名參數和格式JSONEachRow創建。文件 test_function.xml。
<function> <type>executable</type> <name>test_function_sum_json</name> <return_type>UInt64</return_type> <return_name>result_name</return_name> <argument> <type>UInt64</type> <name>argument_1</name> </argument> <argument> <type>UInt64</type> <name>argument_2</name> </argument> <format>JSONEachRow</format> <command>test_function_sum_json.py</command> </function>
user_scripts
文件夾內的腳本文件test_function_sum_json.py
。
#!/usr/bin/python3 import sys import json if __name__ == '__main__': for line in sys.stdin: value = json.loads(line) first_arg = int(value['argument_1']) second_arg = int(value['argument_2']) result = {'result_name': first_arg + second_arg} print(json.dumps(result), end='\n') sys.stdout.flush()
查詢:
SELECT test_function_python(toUInt64(2));
結果:
┌─test_function_sum_json(2, 2)─┐ │ 4 │ └──────────────────────────────┘