跳到主要内容

一个 Rust 函数 = 一个 SQL 函数

属性宏会生成 FFI 包装层、列的读写与注册代码。左边这段是安全的 Rust,和写普通库时没有区别。

src/lib.rs
use duckfn::{
duck_error, duck_scalar_function, duckfn_entrypoint, DuckOptionResult,
};

/// The SQL below is what this function becomes, doc comment and all.
#[duck_scalar_function]
pub fn double_it(v: Option<i64>) -> DuckOptionResult<i64> {
if v == Some(13) {
return Err(duck_error("unlucky input"));
}
Ok(v.map(|x| x * 2))
}

// The symbol DuckDB looks for when it loads the extension.
duckfn_entrypoint!("my_ext");
duckdb -unsigned
-- the extension loads like any other
LOAD './my_ext.duckdb_extension';

SELECT double_it(21); -- 42
SELECT double_it(NULL); -- NULL
SELECT double_it(13); -- error: unlucky input

注释就是每次调用的返回值。加载时要加 -unsigned,因为扩展调用的是 DuckDB 的 C API。

同样的函数,两种写法:四个函数各自写两遍