1use crate::ast::expr::Expr;
7use crate::planner::types::ResolvedType;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum StorageType {
12 Row,
14 Columnar,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum RowIdMode {
21 None,
23 Direct,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum Compression {
30 None,
31 Lz4,
32 Zstd,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct StorageOptions {
38 pub storage_type: StorageType,
39 pub compression: Compression,
40 pub row_group_size: u32,
41 pub row_id_mode: RowIdMode,
42}
43
44impl Default for StorageOptions {
45 fn default() -> Self {
46 Self {
47 storage_type: StorageType::Row,
48 compression: Compression::Lz4,
49 row_group_size: 100_000,
50 row_id_mode: RowIdMode::Direct,
51 }
52 }
53}
54
55#[derive(Debug, Clone)]
81pub struct TableMetadata {
82 pub table_id: u32,
84 pub name: String,
86 pub columns: Vec<ColumnMetadata>,
88 pub primary_key: Option<Vec<String>>,
90 pub storage_options: StorageOptions,
92}
93
94impl TableMetadata {
95 pub fn new(name: impl Into<String>, columns: Vec<ColumnMetadata>) -> Self {
100 Self {
101 table_id: 0,
102 name: name.into(),
103 columns,
104 primary_key: None,
105 storage_options: StorageOptions::default(),
106 }
107 }
108
109 pub fn with_table_id(mut self, table_id: u32) -> Self {
111 self.table_id = table_id;
112 self
113 }
114
115 pub fn with_primary_key(mut self, columns: Vec<String>) -> Self {
117 self.primary_key = Some(columns);
118 self
119 }
120
121 pub fn get_column(&self, name: &str) -> Option<&ColumnMetadata> {
140 self.columns.iter().find(|c| c.name == name)
141 }
142
143 pub fn get_column_index(&self, name: &str) -> Option<usize> {
147 self.columns.iter().position(|c| c.name == name)
148 }
149
150 pub fn column_names(&self) -> Vec<&str> {
167 self.columns.iter().map(|c| c.name.as_str()).collect()
168 }
169
170 pub fn column_count(&self) -> usize {
172 self.columns.len()
173 }
174}
175
176#[derive(Debug, Clone)]
196pub struct ColumnMetadata {
197 pub name: String,
199 pub data_type: ResolvedType,
201 pub not_null: bool,
203 pub primary_key: bool,
205 pub unique: bool,
207 pub default: Option<Expr>,
209}
210
211impl ColumnMetadata {
212 pub fn new(name: impl Into<String>, data_type: ResolvedType) -> Self {
216 Self {
217 name: name.into(),
218 data_type,
219 not_null: false,
220 primary_key: false,
221 unique: false,
222 default: None,
223 }
224 }
225
226 pub fn with_not_null(mut self, not_null: bool) -> Self {
228 self.not_null = not_null;
229 self
230 }
231
232 pub fn with_primary_key(mut self, primary_key: bool) -> Self {
234 self.primary_key = primary_key;
235 self
236 }
237
238 pub fn with_unique(mut self, unique: bool) -> Self {
240 self.unique = unique;
241 self
242 }
243
244 pub fn with_default(mut self, default: Expr) -> Self {
246 self.default = Some(default);
247 self
248 }
249}
250
251#[cfg(test)]
252mod tests {
253 use super::*;
254
255 #[test]
256 fn test_table_metadata_new() {
257 let table = TableMetadata::new("users", vec![]);
258 assert_eq!(table.table_id, 0);
259 assert_eq!(table.name, "users");
260 assert!(table.columns.is_empty());
261 assert!(table.primary_key.is_none());
262 }
263
264 #[test]
265 fn test_table_metadata_with_table_id() {
266 let table = TableMetadata::new("users", vec![]).with_table_id(42);
267 assert_eq!(table.table_id, 42);
268 assert_eq!(table.name, "users");
269 }
270
271 #[test]
272 fn test_table_metadata_with_columns() {
273 let columns = vec![
274 ColumnMetadata::new("id", ResolvedType::Integer),
275 ColumnMetadata::new("name", ResolvedType::Text),
276 ];
277 let table = TableMetadata::new("users", columns);
278
279 assert_eq!(table.columns.len(), 2);
280 assert_eq!(table.columns[0].name, "id");
281 assert_eq!(table.columns[1].name, "name");
282 }
283
284 #[test]
285 fn test_table_metadata_with_primary_key() {
286 let table = TableMetadata::new("users", vec![])
287 .with_primary_key(vec!["id".to_string(), "tenant_id".to_string()]);
288
289 assert_eq!(
290 table.primary_key,
291 Some(vec!["id".to_string(), "tenant_id".to_string()])
292 );
293 }
294
295 #[test]
296 fn test_get_column() {
297 let columns = vec![
298 ColumnMetadata::new("id", ResolvedType::Integer),
299 ColumnMetadata::new("name", ResolvedType::Text),
300 ];
301 let table = TableMetadata::new("users", columns);
302
303 let id_col = table.get_column("id");
304 assert!(id_col.is_some());
305 assert_eq!(id_col.unwrap().name, "id");
306 assert_eq!(id_col.unwrap().data_type, ResolvedType::Integer);
307
308 let name_col = table.get_column("name");
309 assert!(name_col.is_some());
310 assert_eq!(name_col.unwrap().data_type, ResolvedType::Text);
311
312 assert!(table.get_column("unknown").is_none());
313 }
314
315 #[test]
316 fn test_get_column_index() {
317 let columns = vec![
318 ColumnMetadata::new("id", ResolvedType::Integer),
319 ColumnMetadata::new("name", ResolvedType::Text),
320 ColumnMetadata::new("age", ResolvedType::Integer),
321 ];
322 let table = TableMetadata::new("users", columns);
323
324 assert_eq!(table.get_column_index("id"), Some(0));
325 assert_eq!(table.get_column_index("name"), Some(1));
326 assert_eq!(table.get_column_index("age"), Some(2));
327 assert_eq!(table.get_column_index("unknown"), None);
328 }
329
330 #[test]
331 fn test_column_names() {
332 let columns = vec![
333 ColumnMetadata::new("id", ResolvedType::Integer),
334 ColumnMetadata::new("name", ResolvedType::Text),
335 ColumnMetadata::new("age", ResolvedType::Integer),
336 ];
337 let table = TableMetadata::new("users", columns);
338
339 assert_eq!(table.column_names(), vec!["id", "name", "age"]);
340 }
341
342 #[test]
343 fn test_column_count() {
344 let table = TableMetadata::new(
345 "users",
346 vec![
347 ColumnMetadata::new("id", ResolvedType::Integer),
348 ColumnMetadata::new("name", ResolvedType::Text),
349 ],
350 );
351 assert_eq!(table.column_count(), 2);
352 }
353
354 #[test]
355 fn test_column_metadata_new() {
356 let column = ColumnMetadata::new("id", ResolvedType::Integer);
357
358 assert_eq!(column.name, "id");
359 assert_eq!(column.data_type, ResolvedType::Integer);
360 assert!(!column.not_null);
361 assert!(!column.primary_key);
362 assert!(!column.unique);
363 assert!(column.default.is_none());
364 }
365
366 #[test]
367 fn test_column_metadata_constraints() {
368 let column = ColumnMetadata::new("id", ResolvedType::Integer)
369 .with_not_null(true)
370 .with_primary_key(true)
371 .with_unique(true);
372
373 assert!(column.not_null);
374 assert!(column.primary_key);
375 assert!(column.unique);
376 }
377
378 #[test]
379 fn test_storage_options_default() {
380 let options = StorageOptions::default();
381 assert_eq!(options.storage_type, StorageType::Row);
382 assert_eq!(options.compression, Compression::Lz4);
383 assert_eq!(options.row_group_size, 100_000);
384 assert_eq!(options.row_id_mode, RowIdMode::Direct);
385 }
386
387 #[test]
388 fn test_table_metadata_sets_default_storage_options() {
389 let table = TableMetadata::new("users", vec![]);
390 assert_eq!(table.storage_options, StorageOptions::default());
391 }
392}