From e111c4fc61449e5747f3286471b9efdc132e20ca Mon Sep 17 00:00:00 2001 From: Yuriy Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Thu, 28 Dec 2023 10:49:32 +0100 Subject: [PATCH] Implement proper index creation --- minisql/src/main.rs | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/minisql/src/main.rs b/minisql/src/main.rs index 63e809e..999f49a 100644 --- a/minisql/src/main.rs +++ b/minisql/src/main.rs @@ -225,22 +225,15 @@ fn interpret(table_name: TableName, operation: Operation, state: &mut State, con let table: &mut Table = state.table_from_name_mut(&table_name)?; let column_position: ColumnPosition = table.schema.column_position_from_column_name(&column_name)?; - let index: ColumnIndex = ColumnIndex::new(&table.rows); + let mut index: ColumnIndex = ColumnIndex::new(); + let _ = index.update_from_table(&table, column_position)?; + table.attach_index(column_position, index); Ok(Response::IndexCreated) }, } } -impl ColumnIndex { - fn new(rows: &Rows) -> Self { - let index = BTreeMap::new(); - // TODO: Take into account already existing rows - todo!(); - Self { index } - } -} - impl TableSchema { fn get_column(&self, column_name: &ColumnName) -> DbResult<(DbType, ColumnPosition)> { match self.column_name_position_mapping.get_by_left(column_name) { @@ -514,6 +507,11 @@ impl Table { } impl ColumnIndex { + fn new() -> Self { + let index = BTreeMap::new(); + Self { index } + } + fn get(&self, value: IndexableDbValue) -> HashSet { match self.index.get(&value) { Some(set) => set.clone(), @@ -532,6 +530,27 @@ impl ColumnIndex { } } + // Should be used in the case when an indexed is created after the table has existed for a + // while. In such a case you need to build the index from the already existing rows. + fn update_from_table(&mut self, table: &Table, column_position: ColumnPosition) -> DbResult<()> { + for (id, row) in &table.rows { + let value = match row.get(column_position) { + Some(DbValue::Indexable(value)) => { + value.clone() + }, + Some(_) => { + let column_name: ColumnName = table.schema.column_name_from_column_position(column_position)?; + return Err(Error::AttemptToIndexNonIndexableColumn(table.schema.table_name.to_string(), column_name)) + }, + None => { + return Err(Error::ColumnPositionDoesNotExist(table.schema.table_name.to_string(), column_position)) + } + }; + self.add(value, *id) + } + Ok(()) + } + fn remove(&mut self, value: &IndexableDbValue, id_to_be_removed: UUID) -> bool { match self.index.get_mut(value) { Some(ids) => { @@ -565,6 +584,7 @@ enum Error { MissingTypeAnnotationOfColumn(TableName, ColumnPosition), MissingColumnInInsertValues(TableName, ColumnName, InsertionValues), MismatchBetweenInsertValuesAndColumns(TableName, InsertionValues), + AttemptToIndexNonIndexableColumn(TableName, ColumnName), } fn main() {