use rudb_common::{Field, LogicalType};
pub const DUCKDB: &str = "duckdb";
#[must_use]
pub fn database_fields() -> Vec<Field> {
vec![
Field::new("database_name", LogicalType::Varchar),
Field::new("database_oid", LogicalType::BigInt),
Field::new("path", LogicalType::Varchar),
Field::new("comment", LogicalType::Varchar),
Field::new("tags", tags()),
Field::new("internal", LogicalType::Boolean),
Field::new("type", LogicalType::Varchar),
Field::new("readonly", LogicalType::Boolean),
Field::new("encrypted", LogicalType::Boolean),
Field::new("cipher", LogicalType::Varchar),
Field::new("options", tags()),
]
}
#[must_use]
pub fn schema_fields() -> Vec<Field> {
vec![
Field::new("oid", LogicalType::BigInt),
Field::new("database_name", LogicalType::Varchar),
Field::new("database_oid", LogicalType::BigInt),
Field::new("schema_name", LogicalType::Varchar),
Field::new("comment", LogicalType::Varchar),
Field::new("tags", tags()),
Field::new("internal", LogicalType::Boolean),
Field::new("sql", LogicalType::Varchar),
Field::new("parent_schema", LogicalType::Varchar),
Field::new("parent_schema_oid", LogicalType::BigInt),
]
}
#[must_use]
pub fn table_fields() -> Vec<Field> {
vec![
Field::new("database_name", LogicalType::Varchar),
Field::new("database_oid", LogicalType::BigInt),
Field::new("schema_name", LogicalType::Varchar),
Field::new("schema_oid", LogicalType::BigInt),
Field::new("table_name", LogicalType::Varchar),
Field::new("table_oid", LogicalType::BigInt),
Field::new("comment", LogicalType::Varchar),
Field::new("tags", tags()),
Field::new("internal", LogicalType::Boolean),
Field::new("temporary", LogicalType::Boolean),
Field::new("has_primary_key", LogicalType::Boolean),
Field::new("estimated_size", LogicalType::BigInt),
Field::new("column_count", LogicalType::BigInt),
Field::new("index_count", LogicalType::BigInt),
Field::new("check_constraint_count", LogicalType::BigInt),
Field::new("sql", LogicalType::Varchar),
]
}
#[must_use]
pub fn view_fields() -> Vec<Field> {
vec![
Field::new("database_name", LogicalType::Varchar),
Field::new("database_oid", LogicalType::BigInt),
Field::new("schema_name", LogicalType::Varchar),
Field::new("schema_oid", LogicalType::BigInt),
Field::new("view_name", LogicalType::Varchar),
Field::new("view_oid", LogicalType::BigInt),
Field::new("comment", LogicalType::Varchar),
Field::new("tags", tags()),
Field::new("internal", LogicalType::Boolean),
Field::new("temporary", LogicalType::Boolean),
Field::new("column_count", LogicalType::BigInt),
Field::new("sql", LogicalType::Varchar),
Field::new("is_bound", LogicalType::Boolean),
]
}
#[must_use]
pub fn column_fields() -> Vec<Field> {
vec![
Field::new("database_name", LogicalType::Varchar),
Field::new("database_oid", LogicalType::BigInt),
Field::new("schema_name", LogicalType::Varchar),
Field::new("schema_oid", LogicalType::BigInt),
Field::new("table_name", LogicalType::Varchar),
Field::new("table_oid", LogicalType::BigInt),
Field::new("column_name", LogicalType::Varchar),
Field::new("column_index", LogicalType::Integer),
Field::new("comment", LogicalType::Varchar),
Field::new("internal", LogicalType::Boolean),
Field::new("column_default", LogicalType::Varchar),
Field::new("is_nullable", LogicalType::Boolean),
Field::new("data_type", LogicalType::Varchar),
Field::new("data_type_id", LogicalType::BigInt),
Field::new("character_maximum_length", LogicalType::Integer),
Field::new("numeric_precision", LogicalType::Integer),
Field::new("numeric_precision_radix", LogicalType::Integer),
Field::new("numeric_scale", LogicalType::Integer),
Field::new("tags", tags()),
Field::new("is_generated", LogicalType::Boolean),
Field::new("generation_expression", LogicalType::Varchar),
]
}
#[must_use]
pub fn canonical(ty: &LogicalType) -> String {
match ty {
LogicalType::Decimal { .. } => "DECIMAL".to_string(),
LogicalType::List(_) | LogicalType::Array(_, _) => "LIST".to_string(),
LogicalType::Map(_, _) => "MAP".to_string(),
LogicalType::Struct(_) => "STRUCT".to_string(),
LogicalType::Union(_) => "UNION".to_string(),
other => other.to_string(),
}
}
#[must_use]
pub fn numeric_facts(ty: &LogicalType) -> (Option<i32>, Option<i32>, Option<i32>) {
let binary = |bits| (Some(bits), Some(2), Some(0));
match ty {
LogicalType::TinyInt => binary(8),
LogicalType::SmallInt => binary(16),
LogicalType::Integer => binary(32),
LogicalType::BigInt => binary(64),
LogicalType::HugeInt => binary(128),
LogicalType::Float => binary(24),
LogicalType::Double => binary(53),
LogicalType::Decimal { width, scale } => {
(Some(i32::from(*width)), Some(10), Some(i32::from(*scale)))
}
_ => (None, None, None),
}
}
fn tags() -> LogicalType {
LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
}
#[cfg(test)]
mod tests {
use rudb_common::LogicalType;
use super::{
canonical, column_fields, database_fields, numeric_facts, schema_fields, table_fields,
view_fields,
};
#[test]
fn the_five_tables_are_the_shape_the_pin_returns() {
assert_eq!(database_fields().len(), 11);
assert_eq!(schema_fields().len(), 10);
assert_eq!(table_fields().len(), 16);
assert_eq!(view_fields().len(), 13);
assert_eq!(column_fields().len(), 21);
}
#[test]
fn a_numeric_precision_is_bits_everywhere_except_on_a_decimal() {
assert_eq!(numeric_facts(&LogicalType::Integer), (Some(32), Some(2), Some(0)));
assert_eq!(numeric_facts(&LogicalType::Double), (Some(53), Some(2), Some(0)));
assert_eq!(
numeric_facts(&LogicalType::Decimal { width: 9, scale: 2 }),
(Some(9), Some(10), Some(2))
);
assert_eq!(numeric_facts(&LogicalType::UBigInt), (None, None, None));
assert_eq!(numeric_facts(&LogicalType::Varchar), (None, None, None));
}
#[test]
fn a_types_modifiers_are_not_part_of_the_name_the_oid_is_keyed_by() {
assert_eq!(canonical(&LogicalType::Decimal { width: 9, scale: 2 }), "DECIMAL");
assert_eq!(canonical(&LogicalType::list(LogicalType::Integer)), "LIST");
assert_eq!(canonical(&LogicalType::Integer), "INTEGER");
assert_eq!(canonical(&LogicalType::TimestampTz), "TIMESTAMP WITH TIME ZONE");
}
#[test]
fn a_schemas_own_oid_is_spelled_oid_and_not_schema_oid() {
assert_eq!(schema_fields()[0].name, "oid");
assert!(schema_fields().iter().all(|field| field.name != "schema_oid"));
}
}