use std::sync::Arc;
use crate::encoding::integer::RleVersion;
use crate::proto::{column_encoding::Kind as ProtoColumnKind, ColumnEncoding, StripeFooter};
use crate::schema::DataType;
#[derive(Clone, Debug)]
pub struct Column {
footer: Arc<StripeFooter>,
name: String,
data_type: DataType,
}
impl Column {
pub fn new(name: String, data_type: DataType, footer: Arc<StripeFooter>) -> Self {
Self {
footer,
data_type,
name,
}
}
pub fn dictionary_size(&self) -> usize {
let column = self.data_type.column_index();
self.footer.columns[column]
.dictionary_size
.unwrap_or_default() as usize
}
pub fn encoding(&self) -> ColumnEncoding {
let column = self.data_type.column_index();
self.footer.columns[column].clone()
}
pub fn rle_version(&self) -> RleVersion {
match self.encoding().kind() {
ProtoColumnKind::Direct | ProtoColumnKind::Dictionary => RleVersion::V1,
ProtoColumnKind::DirectV2 | ProtoColumnKind::DictionaryV2 => RleVersion::V2,
}
}
pub fn data_type(&self) -> &DataType {
&self.data_type
}
pub fn name(&self) -> &str {
&self.name
}
pub fn column_id(&self) -> u32 {
self.data_type.column_index() as u32
}
pub fn children(&self) -> Vec<Column> {
match &self.data_type {
DataType::Boolean { .. }
| DataType::Byte { .. }
| DataType::Short { .. }
| DataType::Int { .. }
| DataType::Long { .. }
| DataType::Float { .. }
| DataType::Double { .. }
| DataType::String { .. }
| DataType::Varchar { .. }
| DataType::Char { .. }
| DataType::Binary { .. }
| DataType::Decimal { .. }
| DataType::Timestamp { .. }
| DataType::TimestampWithLocalTimezone { .. }
| DataType::Date { .. } => vec![],
DataType::Struct { children, .. } => children
.iter()
.map(|col| Column {
footer: self.footer.clone(),
name: col.name().to_string(),
data_type: col.data_type().clone(),
})
.collect(),
DataType::List { child, .. } => {
vec![Column {
footer: self.footer.clone(),
name: "item".to_string(),
data_type: *child.clone(),
}]
}
DataType::Map { key, value, .. } => {
vec![
Column {
footer: self.footer.clone(),
name: "key".to_string(),
data_type: *key.clone(),
},
Column {
footer: self.footer.clone(),
name: "value".to_string(),
data_type: *value.clone(),
},
]
}
DataType::Union { variants, .. } => {
variants
.iter()
.enumerate()
.map(|(index, data_type)| Column {
footer: self.footer.clone(),
name: format!("{index}"),
data_type: data_type.clone(),
})
.collect()
}
}
}
}