duckdb-rs icon indicating copy to clipboard operation
duckdb-rs copied to clipboard

[Feature] Derive `FromSql`, `ToSql`

Open rm-dr opened this issue 5 months ago • 0 comments

I've been using duckdb for a few months, and have written a crate that allows my team to #[derive] traits equivalent to ToSql and FromSql. Would you consider a PR that integrate these changes into duckdb-rs (gated behind a "derive" feature)?

I'd be happy to adapt my code for duckdb-rs, but would like some buy-in before I start a big pr.

code: https://git.betalupi.com/Mark/libduck crates.io: https://crates.io/crates/libduck

Usage looks something like this:

#[derive(DuckValue, FromDuck, ToDuck)]
pub struct X {
   pub name: String,
   pub desc: Option<String>
}

fn main() {
    let conn = Connection::open_in_memory().unwrap();

    // I use a struct here, but it isn't hard to decode whole rows
    // using a similar process.
    conn.execute_batch(r"CREATE TABLE tb ( x STRUCT (name TEXT, desc TEXT) );").unwrap();
    conn.execute(
        r#"INSERT INTO tb (x) VALUES (struct_pack(name := "imastring"))"#,
        [],
    )
    .unwrap();

    let mut stmt = conn.prepare("SELECT * FROM tb;").unwrap();
    let mut rows = stmt.query([]).unwrap();

    if let Some(row) = rows.next().unwrap() {
        let res: X = FromDuck::from_duck(row.get(0).unwrap()).unwrap();
        println!("{res:?}");
    }
}

Which is significantly nicer than writing duck-to-rust decoders manually.

rm-dr avatar Jul 18 '25 06:07 rm-dr