Back to changelog
New
2 minute read

ClickHouse: WASM Modules and WASM User Defined Functions

Atlas now manages ClickHouse WASM modules and WASM User Defined Functions (UDFs) as first-class resources. Define a wasm_module once in HCL, reference it from one or more function blocks with lang = WASM, and Atlas plans and applies the required SQL.

ClickHouse WASM modules ship a compiled WASM binary into the server, and WASM UDFs expose one of a module's exported functions as a callable SQL function. Atlas models these as two connected resources: a wasm_module that holds the binary and its hash, and a function with lang = WASM that points at a module and names the export to call.

Enabling WASM Support

WASM support is opt-in. Set wasm_modules = true on the ClickHouse schema mode in your env:

atlas.hcl
env "local" {
url = "clickhouse://your_username:your_password@localhost:9000"
dev = "clickhouse://your_username:your_password@localhost:9004"
migration {
dir = "file://migrations"
}
schema {
src = "file://schema/main.hcl"
mode "clickhouse" {
wasm_modules = true
}
}
}

WASM Modules

The new wasm_module resource manages ClickHouse WASM modules. ClickHouse stores modules as binary WASM, so the binary is supplied as base64 or hexadecimal through expressions such as base64Decode(...) or unhex(...).

  • code — expression returning the raw WASM binary from base64 or hexadecimal input. Write-only; never emitted during inspection.
  • hash — expression evaluating to the expected UInt256 SHA-256 hash of the module binary.
schema/main.hcl
wasm_module "math_module" {
code = sql("unhex('0061736d0100000001070160027f7f017f030201000707010373756200000a09010700200020016b0b')")
hash = sql("reinterpretAsUInt256(unhex('a957fcb890da31e0e4a72bbdb0e04c50ba7ff5cb6946b21d674f9dcb6e7cd488'))")
}

Atlas generates:

atlas migrate diff
-- Create wasm module "math_module"
INSERT INTO system.webassembly_modules (name, code, hash) SELECT 'math_module', unhex('0061736d0100000001070160027f7f017f030201000707010373756200000a09010700200020016b0b'), reinterpretAsUInt256(unhex('a957fcb890da31e0e4a72bbdb0e04c50ba7ff5cb6946b21d674f9dcb6e7cd488'));

WASM User Defined Functions

Functions can now be declared with lang = WASM and reference a previously declared wasm_module.

  • lang — must be WASM.
  • returns — function return type.
  • module — reference to a wasm_module resource.
  • source — name of the exported function inside the WASM module.
  • abi — Application Binary Interface version: ROW_DIRECT, BUFFERED_V1, or ASSEMBLYSCRIPT.
  • deterministic — declares the function as deterministic.
  • hash — expected SHA-256 hash of the referenced module. Auto-filled if omitted.
  • settings — per-function ClickHouse settings.
  • arg — declares a function argument, each with a type and an optional name.
schema/main.hcl
function "wasm_numbers" {
lang = WASM
returns = UInt32
module = wasm_module.math_module
source = "sub"
abi = ROW_DIRECT
deterministic = true
hash = "a957fcb890da31e0e4a72bbdb0e04c50ba7ff5cb6946b21d674f9dcb6e7cd488"
settings = {
serialization_format = "MsgPack"
webassembly_udf_enable_fuel = 1
}
arg "a" {
type = UInt32
}
arg "b" {
type = UInt32
}
}

Atlas generates:

atlas migrate diff
-- Create "wasm_numbers" function
CREATE FUNCTION `wasm_numbers`
LANGUAGE WASM
ARGUMENTS (a UInt32, b UInt32)
RETURNS UInt32
FROM 'math_module' :: 'sub'
ABI ROW_DIRECT
DETERMINISTIC
SHA256_HASH 'a957fcb890da31e0e4a72bbdb0e04c50ba7ff5cb6946b21d674f9dcb6e7cd488'
SETTINGS
serialization_format = 'MsgPack',
webassembly_udf_enable_fuel = 1;
featureclickhousewebassemblywasmudffunctions