sql_cli/data/
virtual_table_generator.rs1use anyhow::{anyhow, Result};
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::data::datatable::{DataColumn, DataRow, DataTable, DataType, DataValue};
6
7pub struct VirtualTableGenerator;
8
9impl VirtualTableGenerator {
10 pub fn generate_range(
11 start: i64,
12 end: i64,
13 step: Option<i64>,
14 column_name: Option<String>,
15 ) -> Result<Arc<DataTable>> {
16 let step = step.unwrap_or(1);
17 let column_name = column_name.unwrap_or_else(|| "value".to_string());
18
19 if step == 0 {
20 return Err(anyhow!("RANGE step cannot be zero"));
21 }
22
23 if (step > 0 && start > end) || (step < 0 && start < end) {
24 return Err(anyhow!(
25 "RANGE parameters invalid: start={}, end={}, step={}",
26 start,
27 end,
28 step
29 ));
30 }
31
32 let mut table = DataTable::new("range_table");
33
34 let column = DataColumn {
35 name: column_name,
36 data_type: DataType::Integer,
37 nullable: false,
38 unique_values: Some(0),
39 null_count: 0,
40 metadata: HashMap::new(),
41 qualified_name: None,
42 source_table: None,
43 };
44 table.add_column(column);
45
46 let mut current = start;
47 while (step > 0 && current <= end) || (step < 0 && current >= end) {
48 let row = DataRow {
49 values: vec![DataValue::Integer(current)],
50 };
51 table.add_row(row);
52 current += step;
53 }
54
55 Ok(Arc::new(table))
56 }
57
58 pub fn generate_series(count: i64, start: Option<i64>) -> Result<Arc<DataTable>> {
59 let start = start.unwrap_or(1);
60 Self::generate_range(start, start + count - 1, Some(1), Some("index".to_string()))
61 }
62
63 pub fn generate_split(
65 text: &str,
66 delimiter: Option<&str>,
67 column_name: Option<String>,
68 ) -> Result<Arc<DataTable>> {
69 let delimiter = delimiter.unwrap_or(" ");
70 let column_name = column_name.unwrap_or_else(|| "value".to_string());
71
72 let mut table = DataTable::new("split_table");
73
74 let column = DataColumn {
75 name: column_name,
76 data_type: DataType::String,
77 nullable: false,
78 unique_values: Some(0),
79 null_count: 0,
80 metadata: HashMap::new(),
81 qualified_name: None,
82 source_table: None,
83 };
84 table.add_column(column);
85
86 let index_column = DataColumn {
88 name: "index".to_string(),
89 data_type: DataType::Integer,
90 nullable: false,
91 unique_values: Some(0),
92 null_count: 0,
93 metadata: HashMap::new(),
94 qualified_name: None,
95 source_table: None,
96 };
97 table.add_column(index_column);
98
99 let parts: Vec<String> = if delimiter.is_empty() {
101 text.chars().map(|c| c.to_string()).collect()
103 } else {
104 text.split(delimiter).map(|s| s.to_string()).collect()
105 };
106
107 for (i, part) in parts.iter().enumerate() {
108 if part.is_empty() && delimiter != "" {
110 continue;
111 }
112
113 let row = DataRow {
114 values: vec![
115 DataValue::String(part.clone()),
116 DataValue::Integer((i + 1) as i64),
117 ],
118 };
119 table.add_row(row);
120 }
121
122 Ok(Arc::new(table))
123 }
124}