1use sqlparser::ast::{ColumnOption, ColumnOptionDef, DataType};
4
5use crate::{column::Column, identifier::ColumnRef, value::Value, vm::RuntimeError, BoundedString};
6
7pub(super) const TABLE_UNIQUE_KEY_NAME: &str = "__otter_unique_key";
8
9pub(super) const TABLE_TEMPORARY_NAME: &str = "__otter_temporary_table";
10
11#[derive(Debug, Clone)]
12pub struct Table {
16 name: BoundedString,
17 pub(super) raw_columns: Vec<Column>,
18 pub(super) raw_data: Vec<RawRow>,
21 row_id: u64,
22}
23
24impl Table {
25 pub(super) fn new(name: BoundedString, mut columns: Vec<Column>) -> Self {
26 columns.insert(
28 0,
29 Column::new(
30 TABLE_UNIQUE_KEY_NAME.into(),
31 DataType::UnsignedInt(None),
32 vec![ColumnOptionDef {
33 name: None,
34 option: ColumnOption::Unique { is_primary: false },
35 }],
36 true,
37 ),
38 );
39
40 Self {
41 name,
42 raw_columns: columns,
43 raw_data: Vec::new(),
44 row_id: 0,
45 }
46 }
47
48 pub(super) fn new_temp(num: usize) -> Self {
49 Self::new(
50 format!("{}_{}", TABLE_TEMPORARY_NAME, num).as_str().into(),
51 Vec::new(),
52 )
53 }
54
55 pub(super) fn new_from(table: &Self) -> Self {
56 Self {
57 name: table.name,
58 raw_columns: table.raw_columns.clone(),
59 raw_data: Vec::new(),
60 row_id: 0,
61 }
62 }
63
64 pub fn new_row(&mut self, mut data: Vec<Value>) -> &mut Self {
68 data.insert(0, Value::Int64(self.row_id as i64));
69 self.raw_data.push(RawRow { raw_data: data });
70 self.row_id += 1;
71 self
72 }
73
74 pub fn all_data(&self) -> Vec<Row> {
76 self.raw_data
77 .iter()
78 .cloned()
79 .map(|row| Row::from_raw(row, self))
80 .collect()
81 }
82
83 pub fn name(&self) -> &BoundedString {
85 &self.name
86 }
87
88 pub fn columns(&self) -> impl Iterator<Item = &Column> {
90 self.raw_columns.iter().filter(|c| !c.is_internal())
91 }
92
93 pub fn num_columns(&self) -> usize {
95 self.columns().count()
97 }
98
99 pub fn add_column(&mut self, column: Column) -> &mut Self {
105 self.raw_columns.push(column);
106 self
107 }
108
109 pub fn add_column_data(
111 &mut self,
112 col_name: &BoundedString,
113 data: Vec<Value>,
114 ) -> Result<&mut Self, RuntimeError> {
115 let (col_index, _) = self.get_column(col_name)?;
116
117 if !self.is_empty() && self.raw_data.len() != data.len() {
118 return Err(RuntimeError::TableNewColumnSizeMismatch {
119 table_name: *self.name(),
120 table_len: self.raw_data.len(),
121 col_name: *col_name,
122 col_len: data.len(),
123 });
124 }
125
126 if !self.is_empty() {
127 let first_row_size = self.raw_data[0].raw_data.len();
128 if first_row_size == col_index {
129 for (row, new_data) in self.raw_data.iter_mut().zip(data.into_iter()) {
131 row.raw_data.push(new_data);
132 }
133 } else if first_row_size == self.raw_columns.len() {
134 for (row, new_data) in self.raw_data.iter_mut().zip(data.into_iter()) {
136 row.raw_data[col_index] = new_data;
137 }
138 } else {
139 for (row, new_data) in self.raw_data.iter_mut().zip(data.into_iter()) {
142 row.raw_data.insert(col_index, new_data)
143 }
144 }
145 } else {
146 for value in data {
147 self.new_row(vec![value]);
148 }
149 }
150
151 Ok(self)
152 }
153
154 pub(super) fn get_column(
156 &self,
157 col_name: &BoundedString,
158 ) -> Result<(usize, &Column), RuntimeError> {
159 let idx = self.raw_columns.iter().position(|c| c.name() == col_name);
160 if let Some(idx) = idx {
161 Ok((idx, &self.raw_columns[idx]))
162 } else {
163 return Err(RuntimeError::ColumnNotFound(ColumnRef {
164 schema_name: None,
165 table_name: Some(*self.name()),
166 col_name: *col_name,
167 }));
168 }
169 }
170
171 pub fn get_column_data(&self, col_name: &BoundedString) -> Result<Vec<Value>, RuntimeError> {
173 let (col_index, _) = self.get_column(col_name)?;
174
175 Ok(self
176 .raw_data
177 .iter()
178 .map(|row| row.raw_data[col_index].clone())
179 .collect())
180 }
181
182 pub fn rename(&mut self, new_name: BoundedString) {
184 self.name = new_name;
185 }
186
187 pub fn is_empty(&self) -> bool {
189 self.raw_data.is_empty()
190 }
191
192 pub fn has_no_columns(&self) -> bool {
194 self.columns().next().is_none()
195 }
196
197 pub(super) fn sentinel_row(&self) -> Result<Row, RuntimeError> {
201 let data = self
202 .raw_columns
203 .iter()
204 .map(|c| Value::sentinel_value(c.data_type()))
205 .collect::<Result<Vec<_>, _>>()?;
206 Ok(Row { data })
207 }
208}
209
210#[cfg(feature = "terminal-output")]
211#[cfg_attr(docsrs, doc(cfg(feature = "terminal-output")))]
212impl std::fmt::Display for Table {
213 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
214 use tabled::{builder::Builder, Style};
215
216 let mut builder = Builder::default();
217
218 for row in self.all_data() {
219 builder.add_record(row.data().into_iter().map(|v| v.to_string()));
220 }
221
222 builder.set_columns(self.columns().map(|c| c.name().to_string()));
223
224 let mut table = builder.build();
225
226 table.with(Style::rounded());
227
228 write!(f, "{}", table)
229 }
230}
231
232pub trait RowLike {
234 fn data(self) -> Vec<Value>;
239
240 fn data_shared(&self) -> Vec<&Value>;
242}
243
244#[derive(Debug, Clone, PartialEq)]
246pub struct Row {
247 data: Vec<Value>,
249}
250
251impl RowLike for Row {
252 fn data(self) -> Vec<Value> {
253 self.data
254 }
255
256 fn data_shared(&self) -> Vec<&Value> {
257 self.data.iter().collect()
258 }
259}
260
261impl Row {
262 pub fn new(data: Vec<Value>) -> Self {
263 Self { data }
264 }
265
266 pub(super) fn from_raw(raw: RawRow, table: &Table) -> Row {
267 Row {
268 data: raw
269 .raw_data
270 .into_iter()
271 .enumerate()
272 .filter_map(|(i, value)| {
273 if table.raw_columns[i].is_internal() {
274 None
275 } else {
276 Some(value)
277 }
278 })
279 .collect(),
280 }
281 }
282
283 pub fn to_shared(&self) -> RowShared {
284 RowShared::from_row(self)
285 }
286}
287
288#[derive(Debug, Clone, PartialEq)]
290pub struct RowShared<'a> {
291 data: Vec<&'a Value>,
292}
293
294impl<'a> RowLike for RowShared<'a> {
295 fn data_shared(&self) -> Vec<&Value> {
296 self.data.clone()
297 }
298
299 fn data(self) -> Vec<Value> {
300 self.data.into_iter().cloned().collect()
301 }
302}
303
304impl<'a> RowShared<'a> {
305 pub(super) fn from_raw<'b>(raw: &'a RawRow, table: &'b Table) -> Self {
306 Self {
307 data: raw
308 .raw_data
309 .iter()
310 .enumerate()
311 .filter_map(|(i, value)| {
312 if table.raw_columns[i].is_internal() {
313 None
314 } else {
315 Some(value)
316 }
317 })
318 .collect(),
319 }
320 }
321
322 pub fn from_row(row: &'a Row) -> Self {
323 Self {
324 data: row.data_shared(),
325 }
326 }
327}
328
329impl<'a> From<&'a Row> for RowShared<'a> {
330 fn from(row: &'a Row) -> Self {
331 Self::from_row(row)
332 }
333}
334
335#[derive(Debug, Clone, PartialEq)]
337pub(super) struct RawRow {
338 pub(crate) raw_data: Vec<Value>,
340}
341
342impl RowLike for RawRow {
343 fn data(self) -> Vec<Value> {
344 self.raw_data
345 }
346
347 fn data_shared(&self) -> Vec<&Value> {
348 self.raw_data.iter().collect()
349 }
350}
351
352#[cfg(test)]
353mod tests {
354 use sqlparser::ast::DataType;
355
356 use super::Table;
357 use crate::{column::Column, table::Row, value::Value};
358
359 #[test]
360 fn create_table() {
361 let mut table = Table::new("test".into(), vec![]);
362 assert_eq!(table.name(), "test");
363
364 table.add_column(Column::new(
365 "col1".into(),
366 DataType::Int(None),
367 vec![],
368 false,
369 ));
370
371 table.add_column(Column::new(
372 "col2".into(),
373 DataType::Int(None),
374 vec![],
375 true,
376 ));
377
378 assert_eq!(table.columns().collect::<Vec<_>>().len(), 1);
379 assert_eq!(table.columns().next().unwrap().name(), "col1");
380
381 table.new_row(vec![Value::Int64(1), Value::Int64(2)]);
382
383 assert_eq!(
384 table.all_data(),
385 vec![Row {
386 data: vec![Value::Int64(1)],
387 }]
388 );
389 }
390}