Descripción general
wasm32-unknown-unknown) sin dependencias de un sistema operativo ni de una biblioteca estándar. Además, solo se admite el destino predeterminado de WebAssembly de 32 bits (sin la extensión wasm64).
El módulo debe seguir uno de los protocolos de comunicación (ABI) compatibles para interactuar con ClickHouse.
Una vez compilado, el código binario del módulo se carga en ClickHouse insertándolo en la tabla system.webassembly_modules.
Después, puede crear UDFs que hagan referencia a las funciones exportadas por el módulo mediante la sentencia CREATE FUNCTION ... LANGUAGE WASM.
Requisitos previos
Inicio rápido
wat2wasm de WebAssembly Binary Toolkit (WABT) o el comando parse de wasm-tools.
FORMAT RawBlob para insertarlo en la tabla system.webassembly_modules.
Luego definimos la UDF que hace referencia a la función steps exportada por el módulo:
::, porque es distinto del nombre de la UDF.
Ahora podemos usar la función collatz_steps en nuestras consultas:
number se convierte explícitamente a UInt32, porque las funciones de WebAssembly requieren una coincidencia exacta con los tipos de la firma especificada en la sentencia CREATE FUNCTION.
En el resultado obtuvimos la secuencia de pasos de Collatz para los números del 1 al 100, correspondiente a la secuencia A006577 de la OEIS.
Administrar módulos WASM mediante la tabla del sistema
system.webassembly_modules, que tiene la siguiente estructura:
- Columnas
nameString — Nombre del módulo. No puede estar vacío; solo se permiten caracteres alfanuméricos y guiones bajos.codeString — Código WASM binario sin procesar. Solo escritura; las lecturas devuelven una cadena vacía.hashUInt256 — SHA256 del binario del módulo (cero si está presente en disco, pero aún no se ha cargado).
Insertar un módulo
Listar módulos
Eliminar un módulo
DELETE FROM system.webassembly_modules WHERE name = '...'.
El predicado debe ser name = 'literal' para una coincidencia exacta o name LIKE 'pattern' para eliminar todos los módulos cuyo nombre coincida con el patrón; no se acepta ninguna otra forma.
Crear una UDF de WebAssembly
function_name: Nombre de la función en ClickHouse. Puede ser diferente del nombre de la función exportada en el módulo.FROM 'module_name' :: 'source_function_name': Nombre del módulo WASM cargado y nombre de la función del módulo WASM que se va a usar (de forma predeterminada, function_name)ARGUMENTS: Lista de nombres y tipos de argumentos (los nombres son opcionales y se usan en formatos de serialización que admiten campos con nombre)ABI: Versión de la interfaz binaria de aplicaciónROW_DIRECT: Mapeo directo de tipos, procesamiento fila por filaBUFFERED_V1: Procesamiento por bloques con serialización
DETERMINISTIC: Declara la función como determinista: siempre devuelve el mismo resultado para la misma entrada. Cuando se especifica, ClickHouse puede plegar a constantes las llamadas en las que todos los argumentos son constantes: la función se evalúa una vez durante el análisis de la consulta y el resultado se reutiliza para cada fila.SHA256_HASH: Hash esperado del módulo para su verificación (se completa automáticamente si se omite); puede usarse para garantizar que se cargue el módulo WASM correcto en distintas réplicas.SETTINGS: Configuración por funciónserialization_formatString — Formato de serialización para ABI que lo requiera. Predeterminado:MsgPack.
Versiones de las ABI
ROW_DIRECT: mapeo directo de tipos (solo tipos primitivosInt32,UInt32,Int64,UInt64,Float32,Float64)BUFFERED_V1: tipos complejos con serialización
ABI ROW_DIRECT
- Los argumentos y los tipos de retorno deben ser tipos numéricos
Int32/UInt32/Int64/UInt64/Float32/Float64/Int128/UInt128. - Las cadenas no son compatibles con esta ABI.
- Las firmas deben coincidir con la exportación WASM (
i32/i64/f32/f64/v128). - El módulo no necesita exportar funciones de soporte.
ABI BUFFERED_V1
Esta ABI es experimental y puede cambiar en futuras versiones.
i32 y devuelve un único valor i32.
El código guest procesa los datos y devuelve un puntero al búfer de resultados con los datos del resultado serializados.
El código guest debe proporcionar dos funciones para crear y destruir estos búferes.
Nota para desarrollar UDFs en Rust
clickhouse_create_buffer y clickhouse_destroy_buffer, sino añadir el crate como dependencia. También incluye macros #[clickhouse_wasm_udf] para encapsular tus funciones habituales de Rust en el formato ABI requerido.
Con este crate, puedes escribir UDFs así:
serde.
API del host disponible para los módulos
clickhouse_server_version() -> i64— devuelve la versión del servidor ClickHouse como un entero (p. ej., 25011001 para v25.11.1.1).clickhouse_throw(ptr: i32, size: i32)— genera un error con el mensaje proporcionado. Acepta un puntero a la ubicación de memoria que contiene la cadena con el mensaje de error y el tamaño de la cadena.clickhouse_log(ptr: i32, size: i32)— registra un mensaje en el log de texto del servidor ClickHouse.clickhouse_random(ptr: i32, size: i32)— rellena la memoria con bytes aleatorios.
Configuración
-
webassembly_udf_max_fuel— Límite de fuel por ejecución de una instancia de WebAssembly UDF. Cada instrucción de WebAssembly consume cierta cantidad de fuel. Establézcalo en 0 para no tener límite. -
webassembly_udf_max_memory— Límite de memoria en bytes por instancia de WebAssembly UDF. -
webassembly_udf_max_input_block_size— Número máximo de filas que se pasan a una WebAssembly UDF en un solo bloque. Establézcalo en 0 para procesar todas las filas a la vez. -
webassembly_udf_max_instances— Número máximo de instancias de WebAssembly UDF que pueden ejecutarse en paralelo por función.