Table Metadata

TableDescription reads the column metadata of an existing DuckDB table from inside your extension: column names, whether a column has a DEFAULT, and, with duckdb-1-5, the column count and types. Replacement scans, table functions and copy functions use it to inspect a table before deciding what to do.

No feature flag required for creating a description or reading column names and defaults: duckdb_table_description_* has been in the frozen stable prefix of the extension API (slots 292–297) since v1.2.0. Two accessors, column_count and column_type, were added in DuckDB 1.5 in the unstable region and need duckdb-1-5.

#![allow(unused)]
fn main() {
use quack_rs::table_description::TableDescription;
use libduckdb_sys::duckdb_connection;

unsafe fn demo(con: duckdb_connection) -> Result<(), quack_rs::error::ExtensionError> {
// SAFETY: `con` is a valid, open connection.
let desc = unsafe { TableDescription::create(con, "main", "events") }?;

assert_eq!(desc.column_name(0).as_deref(), Some("id"));
assert_eq!(desc.column_has_default(0), Some(false));
Ok(())
}
}

with_catalog addresses a table in another catalog, and takes None to mean "the default" for either the catalog or the schema:

#![allow(unused)]
fn main() {
use quack_rs::table_description::TableDescription;
use libduckdb_sys::duckdb_connection;
unsafe fn demo(con: duckdb_connection) -> Result<(), quack_rs::error::ExtensionError> {
let desc = unsafe { TableDescription::with_catalog(con, Some("mydb"), None, "events") }?;
let _ = desc;
Ok(())
}
}

API

MethodDescription
TableDescription::create(con, schema, table) (unsafe)Describe schema.table; Err if the table does not exist
TableDescription::with_catalog(con, catalog, schema, table) (unsafe)Describe a fully-qualified table (None = default)
column_name(i)Column name, or None if i is out of range (or the name is not valid UTF-8)
column_has_default(i)Whether the column has a DEFAULT, or None if i is out of range
column_count() ¹Number of columns
column_type(i) ¹Column LogicalType, or None if i is out of range

¹ Requires the duckdb-1-5 feature flag.

Out-of-range indices return None rather than panicking, so a description can be walked without knowing the width up front when duckdb-1-5 is off.

  • Bulk Appender — append_default fills a column without a DEFAULT with NULL, and fails for a DEFAULT that is not a constant (nextval(...), random()), which column_has_default reports as true
  • Type System — what a LogicalType describes