Skip to main content
Rust SDK 处于 alpha 阶段——各版本之间可能出现破坏性的 API 变更。支持纯函数扩展、聚合函数、变长参数函数以及自定义类型(encode、decode、compare、hash),同时也支持 sys_varstatus_varthread_workerkeyring 预览功能。列存储 ABI 目前仅在 C++ SDK 中提供——如果您需要它,请使用 C++ SDK
自定义类型允许您定义新的列类型——例如 RATIONALVECTORINET——这些类型可以与 ORDER BY、索引和聚合函数一起使用。Rust SDK 通过 custom_type! 宏支持此功能,并且对于存储大小取决于列参数的类型,还通过 parameterized_type! 提供支持(请参阅参数化类型)。 本页假设您已经完成了 使用 Rust 构建扩展 的相关步骤。设置(Cargo.toml、manifest.json、cargo-vsql)与之前相同。

何时使用自定义类型

在以下情况下使用自定义类型:
  • 您需要一种二进制的磁盘布局,而标准的 SQL 类型无法表达这种布局(打包的浮点数、固定宽度的整数、二进制标识符)
  • 您的类型具有其自身的排序语义,该语义与字符串字典序不同
  • 您希望服务器正确地索引和哈希值,以便进行 ORDER BYCOUNT(DISTINCT) 和集合操作
如果您只需要可从 SQL 调用的函数,并且您的数据可以轻松地放入 STRINGINTREAL 列中,则不需要自定义类型。

custom_type!

每个自定义类型都需要 4 个回调函数(编码、解码、比较、哈希)和一个默认值。以下是完整的宏签名:
type_namepersisted_lengthmax_decode_buffer_lengthencodedecodecompare 是必需的。hashdefault 是可选的,但建议使用——hash 对于正确的 COUNT(DISTINCT) 和集合操作是必需的,default 用于类型初始化验证。

接收和返回二进制值

接受或返回自定义类型的函数使用原始字节。 输入——InValue::Custom(b) 携带存储的二进制数据,类型为 &[u8]
输出——VdfReturn::Binary(bytes) 将二进制字节发送回服务器:
要在 func! 声明中引用自定义类型,请使用 villagesql::custom!("type_name")

示例:有理数类型

SDK 仓库中的 examples/vsql_rational 是一个可运行的扩展示例,它实现了 RATIONAL 类型。它以小端字节顺序存储一个有理数,作为 16 字节的 i64 值对(分子、分母),并提供算术函数。 以下是核心的编码、解码、比较和哈希实现:
custom_type! 注册和算术 VDF(rational_addrational_sub 等)都在完整的源代码 examples/vsql_rational/src/lib.rs 中。 安装扩展后:
rational_to_real(r RATIONAL) -> REALRATIONAL 值转换为 64 位浮点近似值,方法是将分子除以分母。当您需要用于显示或比较的近似十进制数,但又不想在列中存储有损表示形式时,此函数很有用。

参数化类型

参数化类型需要一个在 CREATE TABLE 时读取的值——例如 VECTOR(3) 中的 3——才能确定其存储大小。custom_type! 无法表达这一点:它的 persisted_length 对于每一列都是单个固定常量。parameterized_type! 是其 参数化的对应物:持久化长度不再固定,而是通过 int_to_paramsresolve_params,根据声明的参数为每一列计算得出。
type_namemax_persisted_lengthmax_decode_buffer_lengthencodedecodecompareint_to_paramsresolve_paramsparams_typeparams_parseparams_to_strings 是必需的。hashdefault 是可选的;intrinsic_default_fn(一个根据 &P 计算默认值的函数,用于默认值取决于参数的情况)也是可选的,并且与 default 互斥。 下面是 padint——一个以固定 8 个字节存储的 i64,带有一个控制补零显示宽度的 width 参数:
接收参数化自定义类型参数的函数看到的是 InValue::CustomWithParams { bytes, params },而不是普通的 InValue::Custom(bytes)——params 是一个 [TypeParams],它是对该列所声明的 key=value 对的只读、零拷贝视图。

包含类型的 extension!

在注册函数和类型时,extension! 块有两个部分:
仅包含函数的扩展会省略 types:。仅包含类型的扩展会保留 funcs: [],其他部分都不省略。

后续步骤

Rust API 参考

关于 InValueVdfReturn 和所有宏的完整参考。

使用 Rust 构建扩展

入门——Cargo 设置、第一个函数、打包和测试。

C++ 自定义类型

C++ 中的自定义类型——make_type<>、编码/解码/比较/哈希、ALTER TABLE 规则。

扩展架构

自定义类型是如何解析、缓存和存储的。