use rudb_common::{LogicalType, Result, Value};
use rudb_functions::{extension_fields, optimizer_fields};
use rudb_opt::UPSTREAM;
use rudb_plan::{Plan, Slice};
use crate::metadata::{Metadata, text};
const BUILT_IN: &str = "(BUILT-IN)";
const EXTENSIONS: &[(&str, bool, &[&str], &str)] = &[
("autocomplete", false, &[], "Adds support for autocomplete in the shell"),
("avro", false, &[], "Adds support for reading Avro files"),
("aws", false, &[], "Provides features that depend on the AWS SDK"),
("azure", false, &[], "Adds a filesystem abstraction for Azure blob storage to DuckDB"),
("core_functions", true, &[], "Core function library"),
("delta", false, &[], "Adds support for Delta Lake"),
("ducklake", false, &[], "Adds support for DuckLake, SQL as a Lakehouse Format"),
("encodings", false, &[], "All unicode encodings to UTF-8"),
("excel", false, &[], "Adds support for Excel-like format strings"),
("fts", false, &[], "Adds support for Full-Text Search Indexes"),
(
"httpfs",
false,
&["http", "https", "s3"],
"Adds support for reading and writing files over a HTTP(S) connection",
),
("iceberg", false, &[], "Adds support for Apache Iceberg"),
("icu", false, &[], "Adds support for time zones and collations using the ICU library"),
("inet", false, &[], "Adds support for IP-related data types and functions"),
("json", false, &[], "Adds support for JSON operations"),
("lance", false, &[], "Adds support for querying Lance datasets"),
("motherduck", false, &["md"], "Enables motherduck integration with the system"),
("mysql_scanner", false, &["mysql"], "Adds support for connecting to a MySQL database"),
("odbc_scanner", false, &["odbc"], "Adds support for connecting to remote databases over ODBC"),
("parquet", true, &[], "Adds support for reading and writing parquet files"),
(
"postgres_scanner",
false,
&["postgres"],
"Adds support for connecting to a Postgres database",
),
("quack", false, &[], "The DuckDB 'Quack' Client/Server Protocol"),
("shell", false, &[], "Adds CLI-specific support and functionalities"),
(
"spatial",
false,
&[],
"Geospatial extension that adds support for working with spatial data and functions",
),
(
"sqlite_scanner",
false,
&["sqlite", "sqlite3"],
"Adds support for reading and writing SQLite database files",
),
("tpcds", false, &[], "Adds TPC-DS data generation and query support"),
("tpch", false, &[], "Adds TPC-H data generation and query support"),
("ui", false, &[], "Adds local UI for DuckDB"),
("unity_catalog", false, &["uc_catalog"], "Adds support for connecting to Unity Catalog"),
(
"vortex",
false,
&[],
"Adds support for reading and writing files using the Vortex file format",
),
("vss", false, &[], "Adds indexing support to accelerate Vector Similarity Search"),
];
pub(crate) fn extensions(plan: &Plan, index: u32, columns: Slice) -> Result<Metadata> {
let mut rows = Vec::with_capacity(EXTENSIONS.len());
for (name, held, aliases, description) in EXTENSIONS {
let version = if *held { env!("CARGO_PKG_VERSION") } else { "" };
rows.push(vec![
text(name),
Value::Boolean(*held),
Value::Boolean(*held),
text(if *held { BUILT_IN } else { "" }),
text(description),
Value::List {
element: LogicalType::Varchar,
values: aliases.iter().map(|alias| text(alias)).collect(),
},
text(version),
text(if *held { "STATICALLY_LINKED" } else { "NOT_INSTALLED" }),
text(""),
Value::Null,
]);
}
Metadata::new("duckdb_extensions", &extension_fields(), &rows, plan, index, columns)
}
pub(crate) fn optimizers(plan: &Plan, index: u32, columns: Slice) -> Result<Metadata> {
let rows: Vec<Vec<Value>> = UPSTREAM.iter().map(|name| vec![text(name)]).collect();
Metadata::new("duckdb_optimizers", &optimizer_fields(), &rows, plan, index, columns)
}
#[cfg(test)]
mod tests {
use super::EXTENSIONS;
#[test]
fn the_extension_list_is_the_pins_list_in_the_pins_order() {
assert_eq!(EXTENSIONS.len(), 31);
let mut sorted: Vec<&str> = EXTENSIONS.iter().map(|(name, ..)| *name).collect();
let written = sorted.clone();
sorted.sort_unstable();
assert_eq!(written, sorted);
}
#[test]
fn the_two_extensions_this_engine_claims_are_the_two_it_has() {
let held: Vec<&str> =
EXTENSIONS.iter().filter(|(_, held, ..)| *held).map(|(name, ..)| *name).collect();
assert_eq!(held, vec!["core_functions", "parquet"]);
}
}