Implement proper index creation

This commit is contained in:
Yuriy Dupyn 2023-12-28 10:49:32 +01:00
parent c8e398a238
commit e111c4fc61

View file

@ -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<UUID> {
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() {