Introduce new simplified Operation type for Interpreter

This commit is contained in:
Yuriy Dupyn 2024-01-27 18:54:54 +01:00
parent cf76cc4d10
commit 935d9814ae
4 changed files with 110 additions and 3 deletions

View file

@ -1,4 +1,5 @@
use crate::type_system::Value; use crate::type_system::Value;
use crate::operation::InsertionValuesForInterpreter;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::slice::SliceIndex; use std::slice::SliceIndex;
@ -42,6 +43,10 @@ impl Row {
Row(vec![]) Row(vec![])
} }
pub fn new_from_insertion_values(insertion_values: InsertionValuesForInterpreter) -> Self {
Row(insertion_values)
}
pub fn with_number_of_columns(number_of_columns: usize) -> Self { pub fn with_number_of_columns(number_of_columns: usize) -> Self {
Row(Vec::with_capacity(number_of_columns)) Row(Vec::with_capacity(number_of_columns))
} }

View file

@ -2,7 +2,7 @@ use crate::error::Error;
use crate::internals::row::{ColumnPosition, Row}; use crate::internals::row::{ColumnPosition, Row};
use crate::schema::{TableName, TableSchema}; use crate::schema::{TableName, TableSchema};
use crate::internals::table::Table; use crate::internals::table::Table;
use crate::operation::{ColumnSelection, Condition, Operation}; use crate::operation::{ColumnSelection, Condition, Operation, OperationForInterpreter, ConditionForInterpreter, ColumnSelectionForInterpreter};
use crate::result::DbResult; use crate::result::DbResult;
use crate::type_system::{DbType, IndexableValue, Value}; use crate::type_system::{DbType, IndexableValue, Value};
use bimap::BiMap; use bimap::BiMap;
@ -65,6 +65,7 @@ impl State {
m m
} }
// TODO: Get rid of this
fn table_from_name<'a>(&'a self, table_name: &TableName) -> DbResult<&'a Table> { fn table_from_name<'a>(&'a self, table_name: &TableName) -> DbResult<&'a Table> {
match self.table_name_position_mapping.get_by_left(table_name) { match self.table_name_position_mapping.get_by_left(table_name) {
Some(table_position) => { Some(table_position) => {
@ -75,6 +76,10 @@ impl State {
} }
} }
fn table_at<'a>(&'a self, table_position: TablePosition) -> &'a Table {
&self.tables[table_position]
}
fn table_from_name_mut<'b: 'a, 'a>( fn table_from_name_mut<'b: 'a, 'a>(
&'b mut self, &'b mut self,
table_name: &TableName, table_name: &TableName,
@ -88,6 +93,10 @@ impl State {
} }
} }
fn table_at_mut<'a>(&'a mut self, table_position: TablePosition) -> &'a mut Table {
&mut self.tables[table_position]
}
fn attach_table(&mut self, table_name: TableName, table: Table) { fn attach_table(&mut self, table_name: TableName, table: Table) {
let new_table_position: TablePosition = self.tables.len(); let new_table_position: TablePosition = self.tables.len();
self.table_name_position_mapping self.table_name_position_mapping
@ -95,7 +104,67 @@ impl State {
self.tables.push(table); self.tables.push(table);
} }
pub fn interpret<'a>(&'a mut self, operation: Operation) -> DbResult<Response<'a>> { pub fn interpret_for_interpreter<'a>(&'a mut self, operation: OperationForInterpreter) -> DbResult<Response<'a>> {
// TODO: lock stuff
use OperationForInterpreter::*;
match operation {
Select(table_position, column_selection, maybe_condition) => {
let table: &Table = self.table_at(table_position);
let selected_rows = match maybe_condition {
None => {
let x = table.select_all_rows(column_selection);
Box::new(x) as Box<dyn Iterator<Item=Row> + 'a + Send>
},
Some(ConditionForInterpreter::Eq(eq_column, value)) => {
let x =
table.select_rows_where_eq(
column_selection,
eq_column,
value,
)?;
Box::new(x) as Box<dyn Iterator<Item=Row> + 'a + Send>
}
};
Ok(Response::Selected(selected_rows))
},
Insert(table_position, values) => {
let table: &mut Table = self.table_at_mut(table_position);
let (id, row) = table.schema().row_from_insertion_values_for_interpreter(values)?;
table.insert_row_at(id, row)?;
Ok(Response::Inserted)
}
Delete(table_position, maybe_condition) => {
let table: &mut Table = self.table_at_mut(table_position);
let rows_affected = match maybe_condition {
None => table.delete_all_rows(),
Some(ConditionForInterpreter::Eq(eq_column, value)) => {
table.delete_rows_where_eq(eq_column, value)?
}
};
Ok(Response::Deleted(rows_affected))
}
CreateTable(table_name, table_schema) => {
let table = Table::new(table_schema);
self.attach_table(table_name, table);
Ok(Response::TableCreated)
}
CreateIndex(table_position, column) => {
let table: &mut Table = self.table_at_mut(table_position);
table.attach_index(column)?;
Ok(Response::IndexCreated)
}
}
}
pub fn interpret<'a>(&'a mut self, operation: Operation) -> DbResult<Response<'a>> {
// TODO: lock stuff // TODO: lock stuff
use Operation::*; use Operation::*;

View file

@ -1,5 +1,7 @@
use crate::schema::{ColumnName, TableName, TableSchema}; use crate::schema::{ColumnName, TableName, TableSchema};
use crate::type_system::Value; use crate::type_system::Value;
use crate::internals::row::ColumnPosition;
use crate::interpreter::TablePosition;
// ==============SQL operations================ // ==============SQL operations================
// TODO: Note that every operation has a table name. // TODO: Note that every operation has a table name.
@ -16,13 +18,25 @@ pub enum Operation {
// DropTable(TableName), // DropTable(TableName),
} }
pub enum OperationForInterpreter {
Select(TablePosition, ColumnSelectionForInterpreter, Option<ConditionForInterpreter>),
Insert(TablePosition, InsertionValuesForInterpreter),
Delete(TablePosition, Option<ConditionForInterpreter>),
CreateTable(TableName, TableSchema),
CreateIndex(TablePosition, ColumnPosition),
}
pub type InsertionValues = Vec<(ColumnName, Value)>; pub type InsertionValues = Vec<(ColumnName, Value)>;
pub type InsertionValuesForInterpreter = Vec<Value>;
pub enum ColumnSelection { pub enum ColumnSelection {
All, All,
Columns(Vec<ColumnName>), Columns(Vec<ColumnName>),
} }
pub type ColumnSelectionForInterpreter = Vec<ColumnPosition>;
pub enum Condition { pub enum Condition {
// And(Box<Condition>, Box<Condition>), // And(Box<Condition>, Box<Condition>),
// Or(Box<Condition>, Box<Condition>), // Or(Box<Condition>, Box<Condition>),
@ -34,6 +48,10 @@ pub enum Condition {
// StringCondition(StringCondition), // StringCondition(StringCondition),
} }
pub enum ConditionForInterpreter {
Eq(ColumnPosition, Value),
}
// enum StringCondition { // enum StringCondition {
// Prefix(ColumnName, String), // Prefix(ColumnName, String),
// Substring(ColumnName, String), // Substring(ColumnName, String),

View file

@ -1,6 +1,6 @@
use crate::error::Error; use crate::error::Error;
use crate::internals::row::{ColumnPosition, Row}; use crate::internals::row::{ColumnPosition, Row};
use crate::operation::{ColumnSelection, InsertionValues}; use crate::operation::{ColumnSelection, InsertionValues, InsertionValuesForInterpreter, ColumnSelectionForInterpreter};
use crate::result::DbResult; use crate::result::DbResult;
use crate::type_system::{DbType, IndexableValue, Uuid, Value}; use crate::type_system::{DbType, IndexableValue, Uuid, Value};
use bimap::BiMap; use bimap::BiMap;
@ -136,6 +136,21 @@ impl TableSchema {
self.column_name_position_mapping.len() self.column_name_position_mapping.len()
} }
pub fn row_from_insertion_values_for_interpreter(
&self,
insertion_values: InsertionValuesForInterpreter,
) -> DbResult<(Uuid, Row)> {
let row: Row = Row::new_from_insertion_values(insertion_values);
let id: Uuid = match row.get(self.primary_key) {
Some(Value::Indexable(IndexableValue::Uuid(id))) => *id,
Some(_) => unreachable!(), // SAFETY: Should be guaranteed by validation
None => unreachable!(), // SAFETY: Should be guaranteed by validation
};
Ok((id, row))
}
pub fn row_from_insertion_values( pub fn row_from_insertion_values(
&self, &self,
insertion_values: InsertionValues, insertion_values: InsertionValues,