clickhouse支持UDF|通過SQL以及配置文件創建自定義函數


 

一、用戶通過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)─┐
│      01 │
│      13 │
│      25 │
└────────┴──────────────────────────────┘

  在以下查詢中的用戶定義函數中調用條件函數:

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)─┐
│      01 │
│      13 │
│      25 │
└────────┴──────────────────────────────┘

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)commandexecute_direct- 如果為假,則執行或命令的腳本名稱。

  3)argument- 帶有type, 和可選參數的參數描述name每個參數都在單獨的設置中進行描述。如果參數名稱是用戶定義的函數格式(如NativeJSONEachRow )的序列化的一部分,則必須指定名稱。默認參數名稱值為c+ argument_number。

  4)format-將參數傳遞給命令的格式。

  5)return_type- 返回值的類型。

  6)return_name- 返回值的名稱。如果返回名稱是用戶定義函數格式(如NativeJSONEachRow)的序列化的一部分,則需要指定返回名稱可選的。默認值為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_direct1,則將command在 user_scripts 文件夾中搜索。可以使用空格分隔符指定其他腳本參數。示例:script_name arg1 arg2如果execute_direct0,command作為 的參數傳遞bin/sh -c默認值為1可選參數。

  15)lifetime- 以秒為單位的函數的重新加載間隔。如果設置為,0則不會重新加載該函數。默認值為0可選參數。

 

  該命令必須從中讀取參數STDIN並將結果輸出到STDOUT. 該命令必須迭代地處理參數。也就是說,在處理了一大塊參數之后,它必須等待下一個塊。

  示例test_function使用 XML 配置 創建。文件 test_function.xml(默認execute_direct1的情況下)。

<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 │
└──────────────────────────────┘

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM