1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-License-Identifier: MIT
// Copyright 2026 Tom F. <https://github.com/tomtom215/>
// My way of giving something small back to the open source community
// and encouraging more Rust development!
//! Builder for registering `DuckDB` table functions.
//!
//! Table functions are the most powerful extension type — they bridge the gap
//! between "toy" and "real" extensions. Unlike scalar or aggregate functions that
//! transform existing data, table functions **generate** data from scratch: reading
//! files, querying remote APIs, parsing custom formats, or producing synthetic datasets.
//!
//! # Table function lifecycle
//!
//! ```text
//! bind ─── declare output schema, read parameters, hint cardinality
//! init ─── allocate global scan state (shared across threads)
//! local_init ─── allocate per-thread scan state (optional, enables parallelism)
//! scan ─── fill output chunk; repeat until chunk size == 0
//! ```
//!
//! # Key types
//!
//! | Type | Purpose |
//! |------|---------|
//! | [`TableFunctionBuilder`] | Registers the table function with `DuckDB` (raw callback mode) |
//! | [`TypedTableFunctionBuilder`] | Closure-based builder with typed, mutable scan state |
//! | [`BindInfo`] | Ergonomic wrapper for `duckdb_bind_info` in bind callbacks |
//! | [`InitInfo`] | Ergonomic wrapper for `duckdb_init_info` in init callbacks |
//! | [`FunctionInfo`] | Ergonomic wrapper for `duckdb_function_info` in scan callbacks |
//! | [`FfiBindData<T>`] | Type-safe bind-phase data storage |
//! | [`FfiInitData<T>`] | Type-safe global init-phase data storage |
//! | [`FfiLocalInitData<T>`] | Type-safe per-thread init-phase data storage |
//!
//! # Two layers: raw vs. typed
//!
//! - Reach for [`TypedTableFunctionBuilder`] first.
//! It hides the bind/init/scan trampolines behind two safe Rust closures, carries a
//! typed scan state from `bind` into `scan`, and catches panics via `catch_unwind`.
//! See the [`typed`] module for the full API and an end-to-end example.
//! - Drop down to [`TableFunctionBuilder`] when you need raw control:
//! projection pushdown with column filtering, `local_init`-driven parallel scans,
//! or any callback shape that doesn't fit the "produce state in bind, mutate it in
//! scan" model.
//!
//! # Example: Simple table function
//!
//! ```rust,no_run
//! use quack_rs::table::{TableFunctionBuilder, FfiBindData, FfiInitData, BindInfo, InitInfo};
//! use quack_rs::types::TypeId;
//! use libduckdb_sys::{duckdb_bind_info, duckdb_init_info, duckdb_function_info,
//! duckdb_data_chunk, duckdb_data_chunk_set_size};
//!
//! struct Config { count: u64 }
//! struct State { row: u64 }
//!
//! unsafe extern "C" fn bind(info: duckdb_bind_info) {
//! unsafe {
//! BindInfo::new(info)
//! .add_result_column("n", TypeId::BigInt)
//! .set_cardinality(3, true);
//! FfiBindData::<Config>::set(info, Config { count: 3 });
//! }
//! }
//!
//! unsafe extern "C" fn init(info: duckdb_init_info) {
//! unsafe { FfiInitData::<State>::set(info, State { row: 0 }); }
//! }
//!
//! unsafe extern "C" fn scan(info: duckdb_function_info, output: duckdb_data_chunk) {
//! unsafe {
//! let cfg = FfiBindData::<Config>::get_from_function(info);
//! let state = FfiInitData::<State>::get_mut(info);
//! if let (Some(cfg), Some(state)) = (cfg, state) {
//! if state.row >= cfg.count {
//! duckdb_data_chunk_set_size(output, 0);
//! return;
//! }
//! // write data into `output`…
//! state.row += 1;
//! duckdb_data_chunk_set_size(output, 1);
//! }
//! }
//! }
//!
//! // fn register(con: libduckdb_sys::duckdb_connection) -> Result<(), quack_rs::error::ExtensionError> {
//! // unsafe {
//! // TableFunctionBuilder::new("generate_n")
//! // .bind(bind)
//! // .init(init)
//! // .scan(scan)
//! // .register(con)
//! // }
//! // }
//! ```
pub use FfiBindData;
pub use ;
pub use ;
pub use ;
pub use TypedTableFunctionBuilder;