概要
wasm32-unknown-unknown) としてコンパイルする必要があります。また、サポートされるのはデフォルトの 32 ビット WebAssembly ターゲットのみです (wasm64 拡張はサポートされません) 。
モジュールは、ClickHouse と連携するために、サポートされている通信プロトコル (ABI) のいずれかに従う必要があります。
コンパイル後、モジュールのバイナリコードは system.webassembly_modules テーブルに insert することで ClickHouse に読み込まれます。
その後、CREATE FUNCTION ... LANGUAGE WASM ステートメントを使用して、モジュールがエクスポートした関数を参照する UDF を作成できます。
前提条件
クイックスタート
wat2wasm、または wasm-tools の parse コマンドを使用できます。
FORMAT RawBlob を使ってバイナリの WASM コードを ClickHouse client に直接パイプし、system.webassembly_modules テーブルに挿入しています。
次に、モジュールからエクスポートされた steps 関数を参照する UDF を定義します。
:: の後にはモジュール内の関数名を指定している点に注意してください。
これで、クエリで collatz_steps 関数を使用できます。
number カラムは、WebAssembly 関数では CREATE FUNCTION ステートメントで指定されたシグネチャどおりに型が完全に一致している必要があるため、明示的に UInt32 にキャストされています。
その結果、1 から 100 までの数に対する Collatz のステップ数列が得られ、これは OEIS の数列 A006577 に対応します。
system table 経由での WASM モジュール管理
system.webassembly_modules テーブルに、次の構造で格納されます。
- カラム
nameString — モジュール名。空は不可で、使用できるのは単語文字のみです。codeString — 生のバイナリ WASM コード。書き込み専用で、読み出し時には空文字列が返されます。hashUInt256 — モジュールバイナリの SHA256 (ディスク上には存在するが、まだ読み込まれていない場合は 0) 。
モジュールを追加する
モジュールを一覧表示
モジュールを削除する
DELETE FROM system.webassembly_modules WHERE name = '...' ステートメントを使用します。
条件式には、完全一致の name = 'literal' または、名前がパターンに一致するすべてのモジュールを削除する name LIKE 'pattern' のいずれかを指定する必要があります。これ以外の形式は受け付けられません。
WebAssembly UDFを作成する
function_name: ClickHouse 内の関数名。モジュール内でエクスポートされた関数名と異なる場合があります。FROM 'module_name' :: 'source_function_name': 読み込まれた WASM モジュール名と、使用する WASM モジュール内の関数名 (デフォルトは function_name)ARGUMENTS: 引数名と型の一覧 (名前は省略可能で、名前付きフィールドをサポートするシリアライゼーションフォーマットで使用されます)ABI: Application Binary Interface のバージョンROW_DIRECT: 直接的な型マッピング、行単位の処理BUFFERED_V1: シリアライゼーションを伴うブロックベースの処理
DETERMINISTIC: 関数を決定論的として宣言します。つまり、同じ入力に対して常に同じ出力を返します。指定すると、ClickHouse はすべての引数が定数である呼び出しを定数畳み込みすることがあります。関数はクエリ解析時に一度評価され、その結果がすべての行で再利用されます。SHA256_HASH: 検証用の想定モジュールハッシュ (省略した場合は自動入力) 。異なるレプリカ間で正しい WASM モジュールが読み込まれていることを保証するために使用できます。SETTINGS: 関数ごとの設定serialization_formatString — ABI で必要なシリアライゼーションフォーマット。デフォルト:MsgPack.
ABI バージョン
ROW_DIRECT: 直接型マッピング (プリミティブ型Int32、UInt32、Int64、UInt64、Float32、Float64のみ)BUFFERED_V1: シリアライゼーションを伴う複合型
ABI ROW_DIRECT
- 引数と戻り値の型には、数値型
Int32/UInt32/Int64/UInt64/Float32/Float64/Int128/UInt128を使用します。 - この ABI では文字列はサポートされていません。
- シグネチャは WASM のエクスポート (
i32/i64/f32/f64/v128) と一致している必要があります。 - モジュール側でエクスポートが必要なサポート関数はありません。
ABI BUFFERED_V1
この ABI は実験的機能であり、今後のリリースで変更される可能性があります。
i32 引数を受け取り、1 つの i32 値を返します。
ゲストコードはデータを処理し、シリアライズされた結果データを含む結果バッファへのポインタを返します。
ゲストコードは、これらのバッファを作成および破棄するための 2 つの関数を提供する必要があります。
RustでUDFを開発する際の注意
clickhouse_create_buffer と clickhouse_destroy_buffer を手動で実装する必要はなく、依存関係として追加するだけで済みます。さらに、通常のRust関数を必要なABI形式でラップするマクロ #[clickhouse_wasm_udf] も用意されています。
このcrateを使うと、次のようにUDFを書けます。
serde を使用してシリアライゼーション/デシリアライゼーションを自動的に処理します。
モジュールから利用できるホスト API
clickhouse_server_version() -> i64— ClickHouse server のバージョンを整数で返します (例: v25.11.1.1 の場合は 25011001) 。clickhouse_throw(ptr: i32, size: i32)— 指定されたメッセージでエラーをスローします。エラーメッセージ文字列を含むメモリ位置へのポインタと、その文字列のサイズを受け取ります。clickhouse_log(ptr: i32, size: i32)— ClickHouse server のテキストログにメッセージを記録します。clickhouse_random(ptr: i32, size: i32)— メモリをランダムなバイト列で埋めます。
設定
-
webassembly_udf_max_fuel— WebAssembly UDF インスタンスの実行ごとの fuel 上限です。各 WebAssembly 命令は一定量の fuel を消費します。制限を設けない場合は 0 に設定します。 -
webassembly_udf_max_memory— WebAssembly UDF インスタンスごとのメモリ上限です (バイト単位) 。 -
webassembly_udf_max_input_block_size— 1 つのブロックで WebAssembly UDF に渡される最大行数です。すべての行を一度に処理する場合は 0 に設定します。 -
webassembly_udf_max_instances— 関数ごとに並列実行できる WebAssembly UDF インスタンスの最大数です。