Skip to main content

linkrs_query/executor/streaming/chunk/
schema.rs

1//! Schema definitions for DataChunk
2
3use linkrs_core::DataType;
4
5/// Simple schema representation
6#[derive(Debug, Clone)]
7pub struct Schema {
8    pub columns: Vec<ColumnInfo>,
9}
10
11#[derive(Debug, Clone)]
12pub struct ColumnInfo {
13    pub name: String,
14    /// Column data type (inferred from values if not specified)
15    ///
16    /// Display-oriented lowercase string (e.g. `"int"`, `"unknown"`).
17    /// Use [`ColumnInfo::typed_data_type`] for the typed view.
18    pub data_type: String,
19}
20
21impl ColumnInfo {
22    /// Typed view of [`ColumnInfo::data_type`].
23    ///
24    /// Unrecognized strings map to `DataType::Unknown` so display-only
25    /// producers never break typed consumers.
26    pub fn typed_data_type(&self) -> DataType {
27        match self.data_type.to_lowercase().as_str() {
28            "bool" => DataType::Bool,
29            "int" | "integer" | "int64" => DataType::Int,
30            "float" | "double" | "float64" => DataType::Float,
31            "string" | "str" => DataType::String,
32            _ => DataType::Unknown,
33        }
34    }
35}
36
37impl Schema {
38    pub fn new(columns: Vec<ColumnInfo>) -> Self {
39        Self { columns }
40    }
41
42    /// Build a schema from names plus resolved types.
43    pub fn with_typed_data_types(names: &[String], types: &[DataType]) -> Self {
44        let columns = names
45            .iter()
46            .enumerate()
47            .map(|(i, name)| {
48                let data_type = types
49                    .get(i)
50                    .map(|dt| dt.to_string().to_lowercase())
51                    .unwrap_or_else(|| "unknown".to_string());
52                ColumnInfo {
53                    name: name.clone(),
54                    data_type,
55                }
56            })
57            .collect();
58        Self { columns }
59    }
60
61    pub fn empty() -> Self {
62        Self { columns: vec![] }
63    }
64
65    pub fn column_count(&self) -> usize {
66        self.columns.len()
67    }
68}