跳到主要内容

安装

添加依赖​

[dependencies]
duckfn = "0.0.18"

# duckfn 基于这两个 crate 构建。只要你直接书写它们的类型或 builder ——
# 例如 SqlMacro、Connection、LogicalType、Value —— 就需要显式添加。
quack-rs = "0.16.0"
# `loadable-extension` 通过 DuckDB 的 API table 分发,而不是链接 libduckdb,
# 这正是无需本地编译 DuckDB 的原因。只用到头文件。
libduckdb-sys = { version = ">=1.4.4, <2", features = ["loadable-extension"] }

duckfn 已重新导出 duckfn-macro 的全部宏,因此上面的片段就够了。 只有想脱离运行时单独使用宏时,才需要直接依赖 duckfn-macro = "0.0.18"。

Cargo feature​

feature作用要求
duckdb-1-5支持 DuckDB 1.5 新增的逻辑类型 —— 目前是 TIME_NS(DuckTimeNs)—— 以及 COPY ... TO 用的 COPY 函数类型。libduckdb-sys 使用 DuckDB 1.5 及以上的头文件。
owned-connection宿主文件系统(duckfn::duck_vfs):注册期捕获一条常驻长连接,让聚合函数这类拿不到客户端上下文的回调也能经 DuckDB 的 VFS 读写文件。它依赖 duckdb-1-5。有副作用:连接跟进程同寿、取用串行,并且在「同线程同步执行 DuckDB」的运行时(DuckDB-Wasm 的 Node blocking 绑定)里会死锁 —— 见文件系统访问。其余与 duckdb-1-5 相同。
chrono时间包装类型与 chrono 的互转(DuckDate::to_naive_date 等),把纪元换算交给 duckfn。由本 feature 引入的可选 chrono 依赖。
uuidDuckUuid 与 uuid 的互转(to_uuid / from_uuid)。可选的 uuid 依赖。
rust_decimalDuckDecimal<W, S> 与 rust_decimal 的互转;越界与丢位都以错误返回。可选的 rust_decimal 依赖。
all聚合开关,一次打开所有可选 feature。随它打开的那些 feature(含 duckdb-1-5 时需要 DuckDB 1.5 头文件)。

三个互转 feature 各自独立,用到哪个开哪个:

duckfn = { version = "0.0.18", features = ["duckdb-1-5", "chrono", "uuid", "rust_decimal"] }

全开就是 duckfn = { version = "0.0.18", features = ["all"] }。它连 cli 一起打开, 而 cli 只多带 clap 与 csv:对要构建 src/bin/duckfn.rs 的那个 crate 无所谓,但想把依赖树 压到最小的话,还是按上面的单项挑。

loadable-extension 是 libduckdb-sys 的 feature,不是 duckfn 的,需要你自己开启。

crate 必须产出 cdylib​

DuckDB 以动态库的形式加载扩展:

[lib]
crate-type = ["cdylib"]

构建 WebAssembly 版本时 crate 类型则要改成 staticlib,因为最终链接由 emcc 完成。做法不是改 lib, 而是给 wasm 那边单独一个 crate root:一个 [[example]] 目标承载 crate-type = ["staticlib"],见 项目结构约定。

为什么不需要本地编译 DuckDB​

通常 DuckDB 扩展需要针对 DuckDB 本体编译并链接,duckfn 避开了这一步:

  1. 开启 loadable-extension 的 libduckdb-sys 只针对 DuckDB 头文件编译,不链接任何库。
  2. DuckDB API 调用走一张函数指针表,宿主 DuckDB 在加载扩展并调用入口点时把这张表填好。

带来的好处是构建快、无外部依赖(交叉编译也能工作),代价是扩展必须与加载它的 DuckDB 版本匹配。 另外扩展被标记为使用 unstable C API,所以加载时必须加 -unsigned。

环境要求​

Rust1.86 及以上(crate 使用 edition 2024)
DuckDB针对 v1.5.6 验证
Python 3 (可选)仅 make configure / make test 流程需要,用于准备 sqllogictest 运行环境

接下来​

  • 快速开始 —— 编写、构建并加载一个扩展。
  • 属性参考 —— 完整的属性与参数说明在指南里。
  • 架构 —— API table 分发到底是怎么工作的。