use rudb_catalog::{Catalog, StoredPart};
use rudb_common::{Result, Value};
use rudb_functions::table::storage_info_fields;
use rudb_parse::identifier_parts;
use rudb_plan::{Plan, Slice};
use crate::metadata::{Metadata, text};
pub(crate) fn storage_info(
catalog: &Catalog,
written: &str,
plan: &Plan,
index: u32,
columns: Slice,
) -> Result<Metadata> {
let parts = identifier_parts(written);
let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
let name = catalog.resolve(&spelled)?;
let table = catalog.table(&name)?;
let mut rows = Vec::new();
for (at, field) in table.columns().iter().enumerate() {
let column = i64::try_from(at).unwrap_or(i64::MAX);
for stored in table.stored(at)? {
rows.push(vec![
Value::BigInt(i64::try_from(stored.stripe).unwrap_or(i64::MAX)),
text(&field.name),
Value::BigInt(column),
text(&format!("[{column}]")),
Value::BigInt(i64::try_from(stored.part).unwrap_or(i64::MAX)),
text(&field.ty.to_string()),
Value::BigInt(i64::try_from(stored.row).unwrap_or(i64::MAX)),
Value::BigInt(i64::try_from(stored.rows).unwrap_or(i64::MAX)),
text(&stored.encoding),
text(&stats(&stored)),
Value::Boolean(false),
Value::Boolean(true),
Value::BigInt(i64::try_from(stored.page).unwrap_or(i64::MAX)),
Value::BigInt(i64::try_from(stored.offset).unwrap_or(i64::MAX)),
text(&format!("{} bytes", stored.bytes)),
Value::List { element: rudb_common::LogicalType::BigInt, values: Vec::new() },
]);
}
}
Metadata::new("pragma_storage_info", &storage_info_fields(), &rows, plan, index, columns)
}
fn stats(stored: &StoredPart) -> String {
let (Some(low), Some(high), Some(nulls)) = (&stored.low, &stored.high, stored.nulls) else {
return "[No Stats]".to_string();
};
format!(
"[Min: {low}, Max: {high}][Has Null: {}, Has No Null: {}]",
nulls > 0,
nulls < stored.rows
)
}