vibesql_executor/
schema.rs1use std::collections::HashMap;
2
3#[derive(Debug, Clone)]
5pub struct CombinedSchema {
6 pub table_schemas: HashMap<String, (usize, vibesql_catalog::TableSchema)>,
9 pub total_columns: usize,
11}
12
13impl CombinedSchema {
14 pub fn from_table(table_name: String, schema: vibesql_catalog::TableSchema) -> Self {
16 let total_columns = schema.columns.len();
17 let mut table_schemas = HashMap::new();
18 table_schemas.insert(table_name.to_lowercase(), (0, schema));
20 CombinedSchema { table_schemas, total_columns }
21 }
22
23 pub fn from_derived_table(
25 alias: String,
26 column_names: Vec<String>,
27 column_types: Vec<vibesql_types::DataType>,
28 ) -> Self {
29 let total_columns = column_names.len();
30
31 let columns: Vec<vibesql_catalog::ColumnSchema> = column_names
33 .into_iter()
34 .zip(column_types)
35 .map(|(name, data_type)| vibesql_catalog::ColumnSchema {
36 name,
37 data_type,
38 nullable: true, default_value: None, })
41 .collect();
42
43 let schema = vibesql_catalog::TableSchema::new(alias.clone(), columns);
44 let mut table_schemas = HashMap::new();
45 table_schemas.insert(alias.to_lowercase(), (0, schema));
47 CombinedSchema { table_schemas, total_columns }
48 }
49
50 pub fn combine(
52 left: CombinedSchema,
53 right_table: String,
54 right_schema: vibesql_catalog::TableSchema,
55 ) -> Self {
56 let mut table_schemas = left.table_schemas;
57 let left_total = left.total_columns;
58 let right_columns = right_schema.columns.len();
59 table_schemas.insert(right_table.to_lowercase(), (left_total, right_schema));
61 CombinedSchema { table_schemas, total_columns: left_total + right_columns }
62 }
63
64 pub fn get_column_index(&self, table: Option<&str>, column: &str) -> Option<usize> {
67 if let Some(table_name) = table {
68 if let Some((start_index, schema)) = self.table_schemas.get(table_name) {
71 return schema.get_column_index(column).map(|idx| start_index + idx);
72 }
73
74 let table_name_lower = table_name.to_lowercase();
76 for (key, (start_index, schema)) in self.table_schemas.iter() {
77 if key.to_lowercase() == table_name_lower {
78 return schema.get_column_index(column).map(|idx| start_index + idx);
79 }
80 }
81 None
82 } else {
83 for (start_index, schema) in self.table_schemas.values() {
85 if let Some(idx) = schema.get_column_index(column) {
86 return Some(start_index + idx);
87 }
88 }
89 None
90 }
91 }
92}
93
94#[derive(Debug)]
99pub struct SchemaBuilder {
100 table_schemas: HashMap<String, (usize, vibesql_catalog::TableSchema)>,
101 column_offset: usize,
102}
103
104impl SchemaBuilder {
105 pub fn new() -> Self {
107 SchemaBuilder { table_schemas: HashMap::new(), column_offset: 0 }
108 }
109
110 pub fn from_schema(schema: CombinedSchema) -> Self {
112 let column_offset = schema.total_columns;
113 SchemaBuilder { table_schemas: schema.table_schemas, column_offset }
114 }
115
116 pub fn add_table(&mut self, name: String, schema: vibesql_catalog::TableSchema) -> &mut Self {
120 let num_columns = schema.columns.len();
121 self.table_schemas.insert(name, (self.column_offset, schema));
122 self.column_offset += num_columns;
123 self
124 }
125
126 pub fn build(self) -> CombinedSchema {
130 CombinedSchema { table_schemas: self.table_schemas, total_columns: self.column_offset }
131 }
132}
133
134impl Default for SchemaBuilder {
135 fn default() -> Self {
136 Self::new()
137 }
138}