Registers an R-backed DuckDB table function. The registered SQL
table function infers its positional SQL argument count from formals(fun)
and registers those arguments with DuckDB's dynamic ANY type. During
DuckDB's bind phase, Rducks converts the actual SQL argument values to R
scalars/lists and calls fun(...) on the recorded calling R thread. fun()
may return either a finite data frame/named list or a
rducks_table_stream() object.
Arguments
- con
A
duckdb_connection.- name
SQL table function name.
- fun
R function returning a data frame, named list of columns, or
rducks_table_stream(). Its finite formal argument count defines the SQL positional argument count; each positional argument is registered as DuckDBANYand converted at bind time from the actual SQL value.- chunk_size
Maximum number of rows emitted per DuckDB output chunk. Must be an integer from 1 to 1024.
Value
Object of class rducks_table_registration containing the
connection and normalized table signature. The table function remains
registered in DuckDB even if this object is discarded.
Details
For finite results, Rducks imports the full result into one DuckDB data chunk
during bind and then emits row batches during scan. For streaming results,
bind uses only the stream prototype to define the DuckDB schema; scan calls
next_batch() repeatedly and imports one returned batch at a time. Both
paths honor DuckDB projection pushdown, so unreferenced columns are not copied
from imported chunks into DuckDB output chunks.
This is intentionally separate from DuckDB scalar-UDF registration through
rducks_register_scalar_udf(): table
functions have their own bind/init/scan state, bind-time dynamic schemas, and
positional SQL arguments fixed by the R function's finite formal argument
count. Variadic ... arguments are not supported. If you already have a
static R data frame to expose as a virtual table, prefer
duckdb::duckdb_register(); DuckDB's R package routes that through its native
data-frame scan path. Use rducks_enable(con, threads = "single") or
otherwise set external_threads=1 plus PRAGMA threads=1 before registration
and execution; worker-thread calls into R are rejected.
Examples
# \donttest{
db <- duckdb::dbConnect(duckdb::duckdb(config = list(allow_unsigned_extensions = "true")))
rducks_enable(db, threads = "single")
rducks_register_table(db, "my_table", function() data.frame(x = 1:3))
#> <rducks_table_registration>
#> registered: yes
#> name: my_table
#> signature: my_table() -> TABLE(<bind-time schema>)
DBI::dbGetQuery(db, "SELECT * FROM my_table()")
#> x
#> 1 1
#> 2 2
#> 3 3
rducks_release(db)
DBI::dbDisconnect(db)
# }