Обзор
wasm32-unknown-unknown) без каких-либо зависимостей от операционной системы или стандартной библиотеки. Кроме того, поддерживается только стандартная 32-битная целевая платформа WebAssembly (без расширения wasm64).
Модуль должен соответствовать одному из поддерживаемых протоколов взаимодействия (ABI) для работы с ClickHouse.
После компиляции бинарный код модуля загружается в ClickHouse путём вставки в таблицу system.webassembly_modules.
После этого вы можете создавать UDF, ссылающиеся на функции, экспортируемые модулем, с помощью оператора CREATE FUNCTION ... LANGUAGE WASM.
Предварительные требования
Быстрый старт
wat2wasm из WebAssembly Binary Toolkit (WABT) или команду parse из wasm-tools.
FORMAT RawBlob, чтобы выполнить вставку в таблицу system.webassembly_modules.
Затем мы определяем UDF, которая ссылается на функцию steps, экспортируемую этим модулем:
:: мы указываем имя функции из модуля, поскольку оно отличается от имени UDF.
Теперь мы можем использовать функцию collatz_steps в запросах:
number явно приводится к типу UInt32, поскольку функции WebAssembly ожидают точного соответствия типов сигнатуре, указанной в операторе CREATE FUNCTION.
В результате мы получили последовательность шагов Коллатца для чисел от 1 до 100, соответствующую последовательности A006577 из OEIS.
Управление модулями WASM через системную таблицу
system.webassembly_modules со следующей структурой:
- Столбцы
nameString — Имя модуля. Не пустое, только буквенно-цифровые символы и знак подчёркивания.codeString — Необработанный бинарный код WASM. Только для записи; при чтении возвращается пустая строка.hashUInt256 — SHA256 бинарного файла модуля (ноль, если он есть на диске, но ещё не загружен).
Добавление модуля
Просмотр списка модулей
Удаление модуля
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 InterfaceROW_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 и возвращает одно значение i32.
Гостевой код обрабатывает данные и возвращает указатель на буфер результата с сериализованными результирующими данными.
Гостевой код должен предоставлять две функции для создания и освобождения этих буферов.
Примечание о разработке пользовательских функций (UDF) на Rust
clickhouse_create_buffer и clickhouse_destroy_buffer — достаточно добавить этот крейт в зависимости. Также в нём есть макросы #[clickhouse_wasm_udf], которые оборачивают обычные функции Rust в требуемый ABI-формат.
С этим крейтом вы можете писать пользовательские функции (UDF) так:
serde.
API хоста, доступный модулям
clickhouse_server_version() -> i64— возвращает версию сервера ClickHouse в виде целого числа (например, 25011001 для v25.11.1.1).clickhouse_throw(ptr: i32, size: i32)— вызывает ошибку с указанным сообщением. Принимает указатель на область памяти, содержащую строку сообщения об ошибке, и размер этой строки.clickhouse_log(ptr: i32, size: i32)— записывает сообщение в текстовый журнал сервера ClickHouse.clickhouse_random(ptr: i32, size: i32)— заполняет память случайными байтами.
Настройки
-
webassembly_udf_max_fuel— Лимит fuel для каждого запуска экземпляра WebAssembly UDF. Каждая инструкция WebAssembly расходует некоторое количество fuel. Установите 0, чтобы снять ограничение. -
webassembly_udf_max_memory— Лимит памяти в байтах для каждого экземпляра WebAssembly UDF. -
webassembly_udf_max_input_block_size— Максимальное количество строк, передаваемых в WebAssembly UDF в одном block. Установите 0, чтобы обрабатывать все строки сразу. -
webassembly_udf_max_instances— Максимальное количество экземпляров WebAssembly UDF, которые могут выполняться параллельно для одной функции.