- 実行可能 UDF は、外部プログラムやスクリプト (Python、Bash など) を起動し、STDIN / STDOUT を介してデータのブロックをストリーミングします。ClickHouse を再コンパイルすることなく、既存のコードやツールを統合するために使用できます。インプロセスの選択肢と比べると呼び出しごとのオーバーヘッドは大きく、より重いロジックや別のランタイムが必要な場合に適しています。
- SQL UDFs は、
CREATE FUNCTIONを使って SQL のみで定義されます。これらはクエリプランにインライン展開されるため (プロセス境界はありません) 、軽量で、式ロジックの再利用や複雑な計算カラムの簡略化に適しています。 - Experimental WebAssembly UDFs は、WebAssembly にコンパイルされたコードを、サーバープロセス内のサンドボックスで実行します。外部の実行可能ファイルよりも呼び出しごとのオーバーヘッドが低く、ネイティブ拡張機能よりも優れた分離性を備えているため、WASM をターゲットにできる言語 (例: C/C++/Rust) で記述されたカスタムアルゴリズムに適しています。
- Experimental driver-based executable UDFs では、オペレーターが提供する “ドライバー” により、
CREATE FUNCTION ... ENGINE = DriverName(...) AS '...'で指定されたコードスニペットを、関数作成時に実行可能 UDF に変換できます (たとえばコンパイルして)。これは実行可能 UDF をベースとしており、サーバー側のドライバー設定が必要です。
実行可能ユーザー定義関数
ClickHouse Cloud では、実行可能 UDF はパブリックベータとして提供されており、Cloud コンソールの UI から作成します。Cloud 固有のワークフローについては、Cloud でのユーザー定義関数 を参照してください。
user_defined_executable_functions_config パラメータで指定します。
関数の設定には、次の項目が含まれます:
コマンドは
STDIN から引数を読み取り、結果を STDOUT に出力する必要があります。また、引数は反復的に処理する必要があります。つまり、1 つの chunk の引数を処理したら、次の chunk を待機しなければなりません。
実行可能ユーザー定義関数
例
インラインスクリプトからの UDF
execute_direct を 0 に明示的に指定し、test_function_sum を手動で作成します。
- XML
- YAML
test_function.xml ファイル (デフォルトのパス設定では /etc/clickhouse-server/test_function.xml) 。/etc/clickhouse-server/test_function.xml
Query
Result
Python スクリプトからの UDF
STDIN から値を読み取り、それを文字列として返す UDF を作成します。
XML または YAML の設定を使用して test_function を作成します。
- XML
- YAML
ファイル
test_function.xml (デフォルトのパス設定では /etc/clickhouse-server/test_function.xml) 。/etc/clickhouse-server/test_function.xml
user_scripts フォルダー内にスクリプトファイル test_function.py を作成します (デフォルトのパス設定では /var/lib/clickhouse/user_scripts/test_function.py) 。
Query
Result
STDIN から 2 つの値を読み取り、その合計を JSON オブジェクトとして返す
test_function_sum_json を作成します。
- XML
- YAML
ファイル
test_function.xml (デフォルトのパス設定では /etc/clickhouse-server/test_function.xml) 。/etc/clickhouse-server/test_function.xml
user_scripts フォルダー内にスクリプトファイル test_function_sum_json.py を作成します (デフォルトのパス設定では /var/lib/clickhouse/user_scripts/test_function_sum_json.py) 。
Query
Result
command 設定でパラメータを使用する
command 設定で構成した定数パラメータを受け取れます (これは executable 型のユーザー定義関数でのみ機能します) 。
また、シェルの引数展開による脆弱性を防ぐため、execute_direct オプションも必要です。
- XML
- YAML
ファイル
test_function_parameter_python.xml (デフォルトのパス設定では /etc/clickhouse-server/test_function_parameter_python.xml) 。/etc/clickhouse-server/test_function_parameter_python.xml
user_scripts フォルダ内にスクリプトファイル test_function_parameter_python.py を作成します (デフォルトのパス設定では /var/lib/clickhouse/user_scripts/test_function_parameter_python.py) 。
Query
Result
シェルスクリプトによるUDF
- XML
- YAML
ファイル
test_function_shell.xml (デフォルトのパス設定の場合は /etc/clickhouse-server/test_function_shell.xml) 。/etc/clickhouse-server/test_function_shell.xml
user_scripts フォルダー内に、スクリプトファイル test_shell.sh を作成します (デフォルトのパス設定の場合は /var/lib/clickhouse/user_scripts/test_shell.sh) 。
/var/lib/clickhouse/user_scripts/test_shell.sh
Query
Result
エラー処理
引数式の評価
&&、||、?: といった演算子です。
ClickHouse では、関数 (演算子) の引数は常に評価されます。
これは、各行を個別に計算するのではなく、カラムのパーツ全体が一度に評価されるためです。
分散クエリ処理における関数の実行
SELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y), では、
distributed_tableに少なくとも2つの分片がある場合、関数 ‘g’ と ‘h’ はリモートサーバーで実行され、関数 ‘f’ はリクエスト元のサーバーで実行されます。distributed_tableに分片が1つしかない場合、‘f’、‘g’、‘h’ のすべての関数はこの分片のサーバーで実行されます。
hostName 関数は、自身が実行されているサーバーの名前を返します。これは、SELECT クエリでサーバーごとに GROUP BY できるようにするためです。
クエリ内の関数がリクエスト元のサーバーで実行されるものの、リモートサーバーで実行する必要がある場合は、その関数を ‘any’ 集約関数でラップするか、GROUP BY のキーに追加できます。
SQL ユーザー定義関数
WebAssembly ユーザー定義関数
クイックスタート
詳細情報
ドライバーベースの実行可能なユーザー定義関数
これは実験的な機能であり、将来のリリースで後方互換性のない変更が加えられる可能性があります。
allow_experimental_executable_udf_drivers サーバー設定で有効にしてください。ENGINE = DriverName(...) で作成すると、ClickHouse はドライバーの create_command を実行し、関数シグネチャとコードのボディを渡します。ドライバーはボディをコンパイルするか、別の方法で処理し、実行可能 UDF の設定を出力します。その後、ClickHouse はその設定を保存して読み込みます。
これにより管理者は、サーバーの設定ファイルやファイルシステムへのアクセスを与えることなく、任意の言語 (たとえば、サンドボックス化されたコンテナー内でコンパイルされる C) で関数を定義できる、安全かつ限定的な手段をユーザーに提供できます。利用可能なドライバーのセットは、オペレーターが完全に制御します。
ドライバーの有効化
-
server configuration で Experimental のゲートを設定します。
-
user_defined_executable_function_drivers_configに 1 つ以上の ドライバー設定 file を指定します (glob を使用可能) 。必要に応じて、生成された実行可能 UDF の configuration が保存されるディレクトリであるdynamic_user_defined_executable_functions_pathも設定します。
SYSTEM RELOAD CONFIG で更新されるため、server を再起動せずにドライバーを追加、変更、削除できます。
ドライバー設定
<driver> を持つ XML (または YAML) ファイルで記述します。サポートされるフィールドは次のとおりです。
ドライバー設定の例:
ドライバー呼び出し契約
CREATE FUNCTION を実行すると、設定された env 変数がセットされた状態で create_command が呼び出され、次の引数が渡されます。
--name <function_name>--return <return_type>(RETURNS句がある場合)--args <signature>(ARGUMENTS句がある場合) 。ここで、signature は宣言された引数の一覧で、たとえばx UInt8, y DateTimeですENGINE = DriverName(key = value)で指定された、宣言済みの各 engine 引数について--<key> <value>
AS の後のテキスト) は、コマンドの標準入力に送られます。コマンドは、実行可能 UDF の configuration を標準出力に出力する必要があります。フォーマットは自動検出され、< で始まる出力は XML、それ以外は YAML として扱われます。生成された configuration 内で定義される関数名は、作成する関数名と一致している必要があります。create_command がゼロ以外の status で終了した場合、ステートメントは終了コードとドライバーの標準エラーを含む例外とともに失敗します。
drop_command は、存在する場合、関数が削除されるときに同じ方法で呼び出されます (stdin に code のボディは渡されません) 。
function の作成
create_command を実行し、生成された設定を dynamic_user_defined_executable_functions_path に書き込みます。すると、既存の実行可能 UDF ローダーがそれを検出します。その後、その関数は他の関数と同様に呼び出せます。
関数の削除
DROP FUNCTION は、ドライバーの drop_command (存在する場合) を呼び出し、生成された動的設定と関数ごとの作業ディレクトリを削除し、実行可能 UDF ローダーを再読み込みして、永続化されたクエリを削除します。
永続化と再起動
ATTACH FUNCTION ... ステートメントとして永続化されるため、サーバーを再起動しても関数は保持されます。起動時には、dynamic_user_defined_executable_functions_path 内の生成済み構成が、ドライバーを再実行することなく直接読み込まれます。永続化された ATTACH FUNCTION に対応する生成済み構成がない場合 (たとえば動的ディレクトリが失われた場合) 、それを再作成するためにドライバーが再実行されます。
制限事項
- この機能は実験的で、
allow_experimental_executable_udf_driversを有効にした場合にのみ利用できます。 - ドライバーベースの関数は、レプリケーション対応のユーザー定義関数ストレージ (
ON CLUSTERおよび<user_defined_zookeeper_path>) ではサポートされていません。レプリケートされるのは生成されたアーティファクトではなく、元のクエリだけであるためです。 - バックアップされたドライバーベースの関数を
RESTOREすると、クエリ自体は保持されますが、ドライバーは再実行されません。生成された設定は、その後の再起動時の復旧によって実体化されます。
例: C ドライバー
programs/server/user_defined_executable_function_drivers_config.d/ 配下に含まれています。これらはあくまで例であり、パッケージには含まれず、インストールもされません。
DockerC- サンドボックス化された Docker コンテナー内でコードをコンパイルして実行し (--network=none --read-only --cap-drop=ALL --security-opt=no-new-privilegesに加えて、メモリ/CPU/PID 制限も適用) 、executable_poolUDF を生成します。GVisorC- コンパイル済みバイナリーを gVisor のrunscランタイム上で実行するバリアントです。UnsafeC- サンドボックスを使用せず、ホスト上でコードを直接コンパイルして実行します。名前のとおり分離は行われないため、信頼できる環境とテスト用途でのみ使用することを想定しています。