diff --git a/minisql/src/type_system.rs b/minisql/src/type_system.rs index 8b95d7b..27a632b 100644 --- a/minisql/src/type_system.rs +++ b/minisql/src/type_system.rs @@ -30,6 +30,18 @@ pub enum IndexableValue { // TODO: what about null? } +impl DbType { + pub fn is_indexable(&self) -> bool { + match self { + Self::String => true, + Self::Int => true, + Self::Number => false, + Self::Uuid => true, + } + } + +} + impl Value { pub fn to_type(&self) -> DbType { match self { diff --git a/parser/src/validation.rs b/parser/src/validation.rs index b36ce55..b818448 100644 --- a/parser/src/validation.rs +++ b/parser/src/validation.rs @@ -20,6 +20,8 @@ pub enum ValidationError { PrimaryKeyMissing(TableName), #[error("multiple primary keys found in table {0}")] MultiplePrimaryKeysFound(TableName), + #[error("attempt to index non-indexable column {1} in table {0}")] + AttemptToIndexNonIndexableColumn(TableName, ColumnName), #[error("type mismatch at column `{column_name:?}` (expected {expected_type:?}, found {received_type:?})")] TypeMismatch { column_name: ColumnName, @@ -202,13 +204,18 @@ fn validate_condition(condition: Option, schema: &TableSchema } fn validate_create_index(table_name: TableName, column_name: ColumnName, db_schema: &DbSchema) -> Result { - // TODO: You should disallow indexing of Number columns. let (table_position, schema) = validate_table_exists(db_schema, &table_name)?; schema - .get_column_position(&column_name) + .get_column(&column_name) .map_or_else( || Err(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()])), - |column| Ok(Operation::CreateIndex(table_position, column)) + |(column, type_)| { + if type_.is_indexable() { + Ok(Operation::CreateIndex(table_position, column)) + } else { + Err(ValidationError::AttemptToIndexNonIndexableColumn(column_name.clone(), table_name)) + } + } ) }