diff --git a/DESIGN.md b/DESIGN.md index 449f983..d94f87b 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -136,7 +136,7 @@ struct TableMetaData { columns: Vec<(ColumnName, DbType, ColumnPosition)> } -fn column_position(TableMetaData, ColumnName) -> ColumnPosition +fn column(TableMetaData, ColumnName) -> ColumnPosition struct Table { meta: TableMetaData, diff --git a/minisql/src/internals/row.rs b/minisql/src/internals/row.rs index 4698ec0..f8a0ea8 100644 --- a/minisql/src/internals/row.rs +++ b/minisql/src/internals/row.rs @@ -4,8 +4,7 @@ use std::ops::{Index, IndexMut}; use std::slice::SliceIndex; use serde::{Deserialize, Serialize}; use crate::restricted_row::RestrictedRow; - -pub type Column = usize; +use crate::schema::Column; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Row(Vec); diff --git a/minisql/src/internals/table.rs b/minisql/src/internals/table.rs index 7609373..9dc05de 100644 --- a/minisql/src/internals/table.rs +++ b/minisql/src/internals/table.rs @@ -3,9 +3,9 @@ use serde::{Deserialize, Serialize}; use crate::error::RuntimeError; use crate::internals::column_index::ColumnIndex; -use crate::internals::row::{Column, Row}; +use crate::internals::row::Row; use crate::restricted_row::RestrictedRow; -use crate::schema::{ColumnName, TableSchema, TableName}; +use crate::schema::{Column, ColumnName, TableSchema, TableName}; use crate::result::DbResult; use crate::type_system::{IndexableValue, Uuid, Value}; diff --git a/minisql/src/interpreter.rs b/minisql/src/interpreter.rs index c1bec89..b019054 100644 --- a/minisql/src/interpreter.rs +++ b/minisql/src/interpreter.rs @@ -1,5 +1,4 @@ -use crate::internals::row::Column; -use crate::schema::{TableName, TableSchema}; +use crate::schema::{Column, TableName, TableSchema}; use crate::internals::table::Table; use crate::operation::{Operation, Condition}; use crate::result::DbResult; @@ -145,7 +144,7 @@ impl State { #[cfg(test)] mod tests { use super::*; - use crate::internals::row::Column; + use crate::schema::Column; use std::collections::HashSet; use crate::type_system::{DbType, IndexableValue, Value}; use crate::operation::Operation; diff --git a/minisql/src/operation.rs b/minisql/src/operation.rs index 3b384bd..6448385 100644 --- a/minisql/src/operation.rs +++ b/minisql/src/operation.rs @@ -1,6 +1,5 @@ -use crate::schema::TableSchema; +use crate::schema::{Column, TableSchema}; use crate::type_system::Value; -use crate::internals::row::Column; use crate::interpreter::TablePosition; // Validated operation. Constructed by validation crate. diff --git a/minisql/src/restricted_row.rs b/minisql/src/restricted_row.rs index 17f4b7a..8ea9aca 100644 --- a/minisql/src/restricted_row.rs +++ b/minisql/src/restricted_row.rs @@ -1,6 +1,6 @@ use std::ops::Index; use std::slice::SliceIndex; -use crate::internals::row::Column; +use crate::schema::Column; use crate::type_system::Value; #[derive(Debug, Clone)] diff --git a/minisql/src/schema.rs b/minisql/src/schema.rs index 8e9423c..7b16656 100644 --- a/minisql/src/schema.rs +++ b/minisql/src/schema.rs @@ -1,4 +1,4 @@ -use crate::internals::row::{Column, Row}; +use crate::internals::row::Row; use crate::operation::{InsertionValues, ColumnSelection}; use crate::result::DbResult; use crate::type_system::{DbType, IndexableValue, Uuid, Value}; @@ -17,6 +17,8 @@ pub struct TableSchema { pub type TableName = String; pub type ColumnName = String; +pub type Column = usize; + impl TableSchema { pub fn new(table_name: TableName, primary_column_name: ColumnName, columns: Vec, types: Vec) -> Self { @@ -47,7 +49,7 @@ impl TableSchema { self.column_name_position_mapping.contains_left(column_name) } - pub fn get_column_position(&self, column_name: &ColumnName) -> Option { + pub fn get_column(&self, column_name: &ColumnName) -> Option { self.column_name_position_mapping.get_by_left(column_name).copied() } @@ -57,13 +59,13 @@ impl TableSchema { selection } - pub fn get_column(&self, column_name: &ColumnName) -> Option<(Column, DbType)> { - let column = self.get_column_position(column_name)?; + pub fn get_typed_column(&self, column_name: &ColumnName) -> Option<(Column, DbType)> { + let column = self.get_column(column_name)?; Some((column, self.column_type(column))) } pub fn get_type_at(&self, column_name: &ColumnName) -> Option { - let position = self.get_column_position(column_name)?; + let position = self.get_column(column_name)?; self.types.get(position).copied() } diff --git a/parser/src/validation.rs b/parser/src/validation.rs index b818448..abeeb86 100644 --- a/parser/src/validation.rs +++ b/parser/src/validation.rs @@ -122,7 +122,7 @@ fn validate_select(table_name: TableName, column_selection: syntax::ColumnSelect Err(ValidationError::ColumnsDoNotExist(non_existant_columns)) } else { let selection: operation::ColumnSelection = - columns.iter().filter_map(|column_name| schema.get_column_position(column_name)).collect(); + columns.iter().filter_map(|column_name| schema.get_column(column_name)).collect(); let validated_condition = validate_condition(condition, schema)?; Ok(Operation::Select(table_position, selection, validated_condition)) } @@ -163,7 +163,7 @@ fn validate_insert(table_name: TableName, insertion_values: syntax::InsertionVal // to get the values in a vector // sorted by the key. for (column_name, value) in insertion_values { - let (column, expected_type) = schema.get_column(&column_name).ok_or(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()]))?; // By the previous validation steps this is never gonna trigger an error. + let (column, expected_type) = schema.get_typed_column(&column_name).ok_or(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()]))?; // By the previous validation steps this is never gonna trigger an error. let value_type = value.to_type(); if value_type != expected_type { return Err(ValidationError::TypeMismatch { column_name: column_name.to_string(), received_type: value_type, expected_type }); @@ -189,7 +189,7 @@ fn validate_condition(condition: Option, schema: &TableSchema Some(condition) => { match condition { syntax::Condition::Eq(column_name, value) => { - let (column, expected_type) = schema.get_column(&column_name).ok_or(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()]))?; + let (column, expected_type) = schema.get_typed_column(&column_name).ok_or(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()]))?; let value_type: DbType = value.to_type(); if expected_type.eq(&value_type) { Ok(Some(operation::Condition::Eq(column, value))) @@ -206,7 +206,7 @@ fn validate_condition(condition: Option, schema: &TableSchema fn validate_create_index(table_name: TableName, column_name: ColumnName, db_schema: &DbSchema) -> Result { let (table_position, schema) = validate_table_exists(db_schema, &table_name)?; schema - .get_column(&column_name) + .get_typed_column(&column_name) .map_or_else( || Err(ValidationError::ColumnsDoNotExist(vec![column_name.to_string()])), |(column, type_)| { diff --git a/server/src/proto_wrapper.rs b/server/src/proto_wrapper.rs index bd74ba6..79cedbd 100644 --- a/server/src/proto_wrapper.rs +++ b/server/src/proto_wrapper.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use minisql::restricted_row::RestrictedRow; -use minisql::schema::TableSchema; -use minisql::type_system::{Value}; +use minisql::schema::{Column, TableSchema}; +use minisql::type_system::Value; use proto::message::backend::{BackendMessage, ColumnDescription, CommandCompleteData, DataRowData, ErrorResponseData, ReadyForQueryData, RowDescriptionData}; use proto::message::primitive::pglist::PgList; use proto::writer::backend::BackendProtoWriter; @@ -58,7 +58,7 @@ impl ServerProto for W where W: BackendProtoWriter + Send { async fn write_table_header(&mut self, table_schema: &TableSchema, row: &RestrictedRow) -> anyhow::Result<()> { let columns = row.iter() - .map(|(index, value)| value_to_column_description(table_schema, value, *index)) + .map(|(column, value)| value_to_column_description(table_schema, value, *column)) .collect::>>()?; self.write_proto(RowDescriptionData { columns: columns.into() }.into()).await?; @@ -84,7 +84,7 @@ impl ServerProto for W where W: BackendProtoWriter + Send { } } -fn value_to_column_description(schema: &TableSchema, value: &Value, index: usize) -> anyhow::Result { +fn value_to_column_description(schema: &TableSchema, value: &Value, index: Column) -> anyhow::Result { let name = schema.column_name_from_column(index); let table_oid = schema.table_name().as_bytes().as_ptr() as i32;