> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> WebAssembly 用户自定义函数文档

# WebAssembly 用户自定义函数

export const ExperimentalBadge = () => {
  return <div className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Experimental 功能。 <u><a href="/docs/beta-and-experimental-features#experimental-features">了解详情。</a></u>
        </div>;
};

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            ClickHouse Cloud 不支持此功能
        </div>;
};

<div id="webassembly-user-defined-functions">
  # WebAssembly 用户自定义函数
</div>

ClickHouse 支持创建以 WebAssembly 编写的用户自定义函数 (UDF) 。这样，你就可以将 Rust、C、C++ 等语言编写的自定义逻辑编译为 WebAssembly 模块并执行。

<div id="overview">
  ## 概述
</div>

WebAssembly 模块是已编译的二进制文件，其中包含一个或多个可由 ClickHouse 调用的函数。
可以将模块看作一个只需加载一次、却能重复多次使用的库或共享对象。

包含 UDF 的 WebAssembly 模块可以使用任何能编译为 WebAssembly 的语言编写，例如 Rust、C 或 C++。

编译为 WebAssembly 的代码 (“guest”代码) 和执行它的 ClickHouse (“host”) 运行在沙箱环境中，只能访问专用的内存空间。

guest 代码会导出 ClickHouse 可调用的函数——这些函数既包括实现自定义逻辑的函数 (用于定义 UDF) ，也包括 ClickHouse 与 WebAssembly 代码之间进行内存管理和数据交换所需的辅助函数。

你的代码应编译为“freestanding” WebAssembly (也称为 `wasm32-unknown-unknown`) ，不依赖任何操作系统或标准库。此外，仅支持默认的 32 位 WebAssembly 目标 (不支持 `wasm64` 扩展) 。
该模块必须遵循一种受支持的通信协议 (ABI) 才能与 ClickHouse 交互。

编译完成后，需要将模块的二进制代码插入 `system.webassembly_modules` 表中，以将其加载到 ClickHouse。
之后，你可以使用 `CREATE FUNCTION ... LANGUAGE WASM` 语句创建引用该模块导出函数的 UDF。

<div id="prerequisites">
  ## 前置条件
</div>

在 ClickHouse 配置中启用 WebAssembly 支持：

```xml theme={null}
<clickhouse>
    <allow_experimental_webassembly_udf>true</allow_experimental_webassembly_udf>
    <webassembly_udf_engine>wasmtime</webassembly_udf_engine>
</clickhouse>
```

可用的引擎实现：

* `wasmtime` (默认，推荐) — 基于 [WasmTime](https://github.com/bytecodealliance/wasmtime)
* `wasmedge` — 基于 [WasmEdge](https://github.com/WasmEdge/WasmEdge)

<div id="quick-start">
  ## 快速入门
</div>

本示例通过实现 [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture) 计算器，演示创建 WebAssembly UDF 的完整流程。

我们将使用 WebAssembly Text 格式 (WAT) 编写代码。它是 WebAssembly 的一种人类可读表示形式，因此在这一阶段无需使用任何编程语言。
ClickHouse 要求模块采用二进制格式，因此我们将使用转换工具将 WAT 转换为 WASM。
要执行此转换，可以使用 [WebAssembly Binary Toolkit (WABT)](https://github.com/WebAssembly/wabt) 中的 `wat2wasm`，或 [wasm-tools](https://github.com/bytecodealliance/wasm-tools) 中的 `parse` 命令。

```bash theme={null}
cat << 'EOF' | wasm-tools parse | clickhouse client -q "INSERT INTO system.webassembly_modules (name, code) SELECT 'collatz', code FROM input('code String') FORMAT RawBlob"
(module
  (func $next (param $n i32) (result i32)
    local.get $n i32.const 1 i32.and
    (if (result i32)
      (then local.get $n i32.const 3 i32.mul i32.const 1 i32.add)
      (else local.get $n i32.const 2 i32.div_u)))
  (func $steps (export "steps") (param $n i32) (result i32)
    (local $count i32)
    local.get $n i32.const 1 i32.lt_u
    (if (then i32.const 0 return))
    (block $done (loop $loop
      local.get $n i32.const 1 i32.eq br_if $done
      local.get $n call $next local.set $n
      local.get $count i32.const 1 i32.add local.set $count
      br $loop))
    local.get $count)
)
EOF
```

在上面的代码片段中，我们使用 `FORMAT RawBlob` 将二进制 WASM 代码直接通过管道传给 ClickHouse 客户端，并将其插入到 `system.webassembly_modules` 表中。

然后，我们定义一个引用该模块导出的 `steps` 函数的 UDF：

```sql theme={null}
CREATE FUNCTION collatz_steps LANGUAGE WASM ARGUMENTS (n UInt32) RETURNS UInt32 FROM 'collatz' :: 'steps';
```

请注意，我们在 `::` 后指定的是模块中的函数名，因为它与 UDF 的名称不同。

现在我们可以在查询中使用 `collatz_steps` 函数：

```sql theme={null}
SELECT groupArray(collatz_steps(number :: UInt32))
FROM numbers(1, 100)
FORMAT TSV
```

`number` 列被显式转换为 `UInt32`，因为 WebAssembly 函数要求类型必须与 `CREATE FUNCTION` 语句中指定的签名精确匹配。

最终结果中，我们得到了 1 到 100 各个数字对应的 Collatz 步骤序列，这与序列 [OEIS 中的 A006577](https://oeis.org/A006577) 相对应。

```text theme={null}
[0,1,7,2,5,8,16,3,19,6,14,9,9,17,17,4,12,20,20,7,7,15,15,10,23,10,111,18,18,18,106,5,26,13,13,21,21,21,34,8,109,8,29,16,16,16,104,11,24,24,24,11,11,112,112,19,32,19,32,19,19,107,107,6,27,27,27,14,14,14,102,22,115,22,14,22,22,35,35,9,22,110,110,9,9,30,30,17,30,17,92,17,17,105,105,12,118,25,25,25]
```

<div id="manage-wasm-modules-via-system-table">
  ## 通过系统表管理 WASM 模块
</div>

WebAssembly 模块存储在 `system.webassembly_modules` 表中，其结构如下：

* **列**
  * `name` String — 模块名称。不能为空，且只能包含词字符。
  * `code` String — 原始 WASM 二进制代码。仅可写，读取时返回空字符串。
  * `hash` UInt256 — 模块二进制文件的 SHA256 (如果文件已存在于磁盘上但尚未加载，则为零) 。

模块管理通过对该表执行标准 SQL 操作进行：

<div id="insert-a-module">
  ### 插入模块
</div>

```sql theme={null}
INSERT INTO system.webassembly_modules (name, code)
SELECT 'my_module', base64Decode('AGFzbQEAAAA...');
```

可选择提供完整性哈希：

```sql theme={null}
INSERT INTO system.webassembly_modules (name, code, hash)
SELECT 'my_module', base64Decode('...'), reinterpretAsUInt256(unhex('369f...c57d'));
```

如果提供的哈希值与模块代码计算出的 SHA256 不一致，则插入会失败。在从 S3 或 HTTP 等外部来源加载模块时，这会很有用。

<div id="distribute-a-module-across-a-cluster">
  ### 在 cluster 中分发模块
</div>

`system.webassembly_modules` 是按实例划分的表——`INSERT` 只会写入处理该 connection 的副本。`INSERT` statement 没有 `ON CLUSTER` 这种形式，因此后续执行 `CREATE FUNCTION ... ON CLUSTER` 时，会在没有该模块的副本上失败：

```text theme={null}
Code: 674. DB::Exception: WebAssembly module 'collatz' not found:
while adding user defined function `collatz_steps`. (RESOURCE_NOT_FOUND)
```

要将 `insert` 操作发送到每个节点，请写入 `cluster` 表函数，而不是本地的 `system.webassembly_modules` 表：

```bash theme={null}
cat collatz.wasm | clickhouse client -q "
  INSERT INTO FUNCTION cluster('default', 'system', 'webassembly_modules') (name, code)
  SELECT 'collatz', code FROM input('code String') FORMAT RawBlob"
```

<Note>
  这种方式依赖底层分布式写入路径访问每个分片中的所有副本，而这只有在集群配置为 `internal_replication=false` 时才会发生。启用 `internal_replication=true` 时 (对于使用 `ReplicatedMergeTree` 自行完成复制的集群，这是默认设置) ，insert 只会发送到每个分片中一个健康的副本，而 `system.webassembly_modules` 不会通过这条路径进行复制，因此某些副本仍然会缺少该模块。在这种配置下，你需要分别向每个副本执行 insert，例如遍历 `system.clusters`，并通过每台主机的 `remote(...)` 写入，或者将二进制文件复制到每台主机上的 `user_scripts/wasm/` 目录中。

  你可以通过 `SELECT cluster, shard_num, internal_replication FROM system.clusters` 查看集群的 `internal_replication`。
</Note>

在扇出式 insert 之后，该模块会出现在每个副本上，并且 `CREATE FUNCTION ... ON CLUSTER` 将成功执行：

```sql theme={null}
CREATE FUNCTION collatz_steps ON CLUSTER 'default'
LANGUAGE WASM FROM 'collatz' :: 'steps'
ARGUMENTS (n UInt32) RETURNS UInt32;
```

你可以使用 `clusterAllReplicas` 验证该模块是否已在所有节点上加载：

```sql theme={null}
SELECT hostName(), name FROM clusterAllReplicas('default', system.webassembly_modules) WHERE name = 'collatz';
```

向 `system.webassembly_modules` 执行插入时，对于相同的 `(name, hash)` 组合是幂等的，因此重新运行分发式插入是安全的，也是在某个副本被替换后修复状态的合理方式。请注意，新加入的服务器不会自动补收已有模块——你必须针对更新后的集群重新运行插入，或者将该 binary 放到新 host 上的 `user_scripts/wasm/` 目录中。

<div id="list-modules">
  ### 列出模块
</div>

```sql theme={null}
SELECT name, lower(hex(reinterpretAsFixedString(hash))) AS sha256 FROM system.webassembly_modules

   ┌─name────┬─sha256───────────────────────────────────────────────────────────┐
1. │ collatz │ a084a10b7b5cb07db198bc93bf1f3c1f8cb8ef279df7a4f6b66b1cdd55d79c48 │
   └─────────┴──────────────────────────────────────────────────────────────────┘
```

<div id="delete-a-module">
  ### 删除模块
</div>

通过执行 `DELETE FROM system.webassembly_modules WHERE name = '...'` 语句删除模块。
该谓词必须是精确匹配的 `name = 'literal'`，或用于删除所有名称匹配该模式的模块的 `name LIKE 'pattern'`；不接受其他形态。

```sql theme={null}
DELETE FROM system.webassembly_modules WHERE name = 'collatz';

-- 批量删除所有名称以 `tmp_` 开头的模块（字面下划线需转义为 `\_`）：
DELETE FROM system.webassembly_modules WHERE name LIKE 'tmp\_%';
```

如果现有 UDFs 中有任何一个引用了某个匹配模块，删除操作将失败，因此必须先删除这些 UDFs。

<div id="create-a-webassembly-udf">
  ## 创建 WebAssembly UDF
</div>

**语法**:

```sql theme={null}
CREATE [OR REPLACE] FUNCTION function_name
LANGUAGE WASM
FROM 'module_name' [:: 'source_function_name']
ARGUMENTS ( [name type[, ...]] | [type[, ...]] )
RETURNS return_type
[ABI ROW_DIRECT | ABI BUFFERED_V1 | ABI ASSEMBLYSCRIPT]
[DETERMINISTIC]
[SHA256_HASH 'hex']
[SETTINGS key = value[, ...]];
```

**参数**：

* `function_name`：ClickHouse 中的函数名称。可能与模块中导出的函数名不同。
* `FROM 'module_name' :: 'source_function_name'`：已加载的 WASM 模块名称，以及要使用的 WASM 模块中的函数名称 (默认为 function\_name)
* `ARGUMENTS`：参数名称和类型列表 (名称为可选项，用于支持命名字段的序列化格式)
* `ABI`：应用程序二进制接口版本
  * `ROW_DIRECT`：直接类型映射，按行处理
  * `BUFFERED_V1`：基于块的处理，带序列化
  * `ASSEMBLYSCRIPT`：适用于由 [AssemblyScript](https://www.assemblyscript.org) 编译器生成的模块的按行处理。数值类型会映射到 AssemblyScript 基本类型；ClickHouse `String` 会映射到 AssemblyScript `string`。
* `DETERMINISTIC`：将该函数声明为确定性的——对于相同输入始终返回相同输出。指定后，当所有参数都是常量时，ClickHouse 可能会对调用进行常量折叠：函数会在查询分析阶段求值一次，结果会复用于每一行。
* `SHA256_HASH`：用于校验的预期模块哈希 (若省略则自动填充) ，可用于确保不同副本上加载的是正确的 WASM 模块。
* `SETTINGS`：函数级设置
  * `serialization_format` String —— ABI 要求的序列化格式。支持的值：`MsgPack`、`JSONEachRow`、`CSV`、`TSV`、`TSVRaw`、`RowBinary` 和 `Buffers`。默认值：`MsgPack`。像 `Buffers` 这样基于块的格式必须返回单列，且该列的类型必须与声明的函数签名匹配。
  * `webassembly_udf_enable_fuel` Bool —— 为该函数启用有限 fuel 预算。默认值：`true`。当为 `false` 时，查询级设置 `webassembly_udf_max_fuel` 会被该函数忽略。使用 `wasmtime` engine 时，禁用 fuel 限制可能会提升性能。但是，对于不受信任或有缺陷的 guest 代码，这可能会增加失控执行的风险。

<div id="abis-versions">
  ## ABI 版本
</div>

要与 ClickHouse 交互，WebAssembly 模块必须遵循受支持的 ABI (应用程序二进制接口) 之一。

* `ROW_DIRECT`：直接类型映射 (仅支持基本类型 `Int32`、`UInt32`、`Int64`、`UInt64`、`Float32`、`Float64`)
* `BUFFERED_V1`：通过序列化处理复杂类型
* `ASSEMBLYSCRIPT`：与 [AssemblyScript](https://www.assemblyscript.org) 模块按行互操作；支持数值类型和 `String`。

<div id="abi-row_direct">
  ### ABI ROW\_DIRECT
</div>

按行直接调用导出的 WASM 函数。

* 参数和返回值类型均为数值类型：`Int32/UInt32/Int64/UInt64/Float32/Float64/Int128/UInt128`。
* 此 ABI 不支持字符串。
* 签名必须与 WASM 导出一致 (`i32/i64/f32/f64/v128`) 。
* 模块无需导出任何辅助函数。

例如，对于签名如下的函数：

```
(func (param i32 i64 f32) (result f64) ...)
```

可按如下方式创建：

```sql theme={null}
CREATE FUNCTION my_func ARGUMENTS (Int32, UInt64, Float32) RETURNS Float64 ...
```

WebAssembly 不区分有符号参数和无符号参数，而是通过不同的指令来解释这些值。因此，参数的大小必须严格一致，而是否有符号则由函数内部的操作决定。

<div id="abi-buffered_v1">
  ### ABI BUFFERED\_V1
</div>

<Note>
  此 ABI 仍处于 Experimental 阶段，未来版本中可能会发生变化。
</Note>

通过 WASM 内存中的 (反) 序列化一次处理整个块。支持任意参数和返回类型。

序列化后的数据会被复制到 WASM 内存中，并将指向缓冲区的指针 (缓冲区由数据指针和数据大小组成) 以及输入中的行数一并传递给 UDF 函数。因此，WASM 侧的用户自定义函数始终接收两个 `i32` 参数，并返回单个 `i32` 值。
guest 侧代码处理数据后，会返回一个指向结果缓冲区的指针，其中包含序列化后的结果数据。

guest 侧代码必须提供两个函数，用于创建和销毁这些缓冲区。

```
(module
  ;; 分配指定大小的新缓冲区
  ;; 返回：Buffer 结构的句柄（非直接数据指针！），包含指向数据的指针及数据大小
  (func (export "clickhouse_create_buffer")
    (param $size i32)    ;; 要分配的数据大小
    (result i32))        ;; 返回具有足够空间的缓冲区句柄

  ;; 通过句柄释放缓冲区
  (func (export "clickhouse_destroy_buffer")
    (param $handle i32)  ;; 要释放的缓冲区句柄
    (result))            ;; 无返回值

    ;; 用户自定义函数
    (func (export "user_defined_function1")
      (param $input_buffer_handle i32)  ;; 输入缓冲区句柄
      (param $n i32)                    ;; 输入的行数
      (result i32))                     ;; 返回输出缓冲区句柄
)
```

C 定义示例：

```c theme={null}
typedef struct {
    uint8_t * data;
    uint32_t size;
} ClickhouseBuffer;

ClickhouseBuffer * clickhouse_create_buffer(uint32_t size) { /* ... */ }

void clickhouse_destroy_buffer(ClickhouseBuffer * data) { /* ... */ }

/// 示例用户自定义函数
ClickhouseBuffer * user_defined_function1(ClickhouseBuffer * span, uint32_t n) { /* ... */ }
ClickhouseBuffer * user_defined_function2(ClickhouseBuffer * span, uint32_t n) { /* ... */ }
```

<div id="abi-assemblyscript">
  ### ABI ASSEMBLYSCRIPT
</div>

适用于由 [AssemblyScript](https://www.assemblyscript.org) 编译器生成的模块。每一行都会触发一次对导出函数的调用，将 ClickHouse 值映射为 AssemblyScript 基本类型和字符串对象。

**支持的类型**：

* 数值类型：`Int8`/`UInt8`、`Int16`/`UInt16` (在边界处扩展为 `i32`) 、`Int32`/`UInt32`、`Int64`/`UInt64`、`Float32`、`Float64`

* `String` — 映射为 AssemblyScript `string` (WASM 内存中的 UTF-16) 。ClickHouse 会自动处理 UTF-8 ↔ UTF-16 的转换。

* 不支持将自定义 AssemblyScript 类用作参数类型或返回类型——它们的运行时类 id 在不同编译结果之间并不稳定 (参见 [AssemblyScript#2982](https://github.com/AssemblyScript/assemblyscript/issues/2982)) 。

**模块要求**：

模块必须使用 AssemblyScript 托管运行时进行编译，以便导出 `__new`、`__pin` 和 `__unpin`。标准的输入/输出字符串处理依赖这些。推荐的调用方式：

```bash theme={null}
asc src.ts --runtime incremental --exportRuntime -o src.wasm
```

AssemblyScript 还会导入 `env.abort`，用于处理运行时陷阱 (如内存不足、边界检查等) 。ClickHouse 会自动提供此导入：当触发 `abort` 时，当前查询会因 `WASM_ERROR` Exception 而失败，并包含已解码的 AssemblyScript 消息和源位置。

**示例**:

```typescript theme={null}
// src.ts
export function add(a: u32, b: u32): u32 {
  return a + b;
}

export function greet(name: string): string {
  return "Hello, " + name + "!";
}
```

使用 `asc` 编译并将生成的 `.wasm` 加载到 `system.webassembly_modules` 后，可按如下方式声明 UDF：

```sql theme={null}
CREATE FUNCTION as_add
    LANGUAGE WASM ABI ASSEMBLYSCRIPT
    FROM 'as_example' :: 'add'
    ARGUMENTS (a UInt32, b UInt32) RETURNS UInt32;

CREATE FUNCTION as_greet
    LANGUAGE WASM ABI ASSEMBLYSCRIPT
    FROM 'as_example' :: 'greet'
    ARGUMENTS (name String) RETURNS String;
```

<div id="note-for-developing-udfs-in-rust">
  ### 关于用 Rust 开发 UDF 的说明
</div>

对于 Rust 程序，我们提供了一个辅助 crate [clickhouse-wasm-udf](https://crates.io/crates/clickhouse-wasm-udf)，可简化为 ClickHouse 开发 WebAssembly UDF 的过程。该 crate 提供了内存管理功能，因此你无需手动实现 `clickhouse_create_buffer` 和 `clickhouse_destroy_buffer` 函数，只需将该 crate 添加为依赖即可。此外，还提供了宏 `#[clickhouse_wasm_udf]`，可将普通的 Rust 函数封装为所需的 ABI 格式。

借助这个 crate，你可以像这样编写 UDF：

```rust theme={null}

use clickhouse_wasm_udf_bindgen::clickhouse_udf;

#[clickhouse_udf]
pub fn some_udf(data: String) -> HashMap<String, String> {
    // 在此处填写您的实现
}

```

宏会生成一个包装函数，用于接收并返回缓冲区结构，并使用 `serde` 自动处理序列化和反序列化。

<div id="host-api-available-to-modules">
  ## 模块可用的宿主 API
</div>

模块可导入并使用以下宿主函数：

* `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)` — 用随机字节填充内存。
* `env.abort(message: i32, fileName: i32, line: i32, column: i32)` — 为与 AssemblyScript 兼容的模块提供。调用它 (或触发会调用它的 AssemblyScript 运行时陷阱) 会以包含已解码消息和源代码位置的 `WASM_ERROR` 异常终止 UDF。未导入 \`env.abort\`\` 的模块不受影响。

<div id="settings">
  ## 设置
</div>

以下查询级设置用于控制 WebAssembly UDF 的执行：

* `webassembly_udf_max_fuel` — 每个 WebAssembly UDF 实例每次执行的 fuel 上限。每条 WebAssembly 指令都会消耗一定数量的 fuel。在传递给 runtime 之前，该值会先按 1024 进行缩放，因此 `webassembly_udf_max_fuel = 1` 对应大约 1024 个 fuel 单位。设为 0 表示没有有限上限。仅适用于每函数设置 `webassembly_udf_enable_fuel` 为 true 的函数，默认即为如此。

* `webassembly_udf_max_memory` — 每个 WebAssembly UDF 实例的内存上限 (以字节为单位) 。

* `webassembly_udf_max_input_block_size` — 单个块中传递给 WebAssembly UDF 的最大行数。设为 0 表示一次处理所有行。

* `webassembly_udf_max_instances` — 每个函数可并行运行的 WebAssembly UDF 实例最大数量。

示例用法：

```sql theme={null}
SET webassembly_udf_max_fuel = 200000;
SELECT my_wasm_udf(column) FROM table;
```

<div id="see-also">
  ## 另请参阅
</div>

* [ClickHouse UDF 概述](/zh/reference/functions/regular-functions/udf)
