diff --git a/bustubx/src/catalog/column.rs b/bustubx/src/catalog/column.rs index 0bc3532..13d9455 100644 --- a/bustubx/src/catalog/column.rs +++ b/bustubx/src/catalog/column.rs @@ -2,11 +2,13 @@ use derive_with::With; use std::sync::Arc; use crate::catalog::DataType; +use crate::common::TableReference; pub type ColumnRef = Arc; #[derive(Debug, Clone, With)] pub struct Column { + pub relation: Option, pub name: String, pub data_type: DataType, pub nullable: bool, @@ -23,6 +25,7 @@ impl Eq for Column {} impl Column { pub fn new(name: String, data_type: DataType, nullable: bool) -> Self { Self { + relation: None, name, data_type, nullable, diff --git a/bustubx/src/catalog/schema.rs b/bustubx/src/catalog/schema.rs index 6770eef..5d40c6b 100644 --- a/bustubx/src/catalog/schema.rs +++ b/bustubx/src/catalog/schema.rs @@ -1,5 +1,6 @@ use super::column::{Column, ColumnRef}; use crate::catalog::DataType; +use crate::common::TableReference; use crate::error::BustubxResult; use crate::BustubxError; use std::sync::Arc; @@ -48,8 +49,12 @@ impl Schema { })) } - pub fn column_with_name(&self, name: &str) -> BustubxResult { - let index = self.index_of(name)?; + pub fn column_with_name( + &self, + relation: Option<&TableReference>, + name: &str, + ) -> BustubxResult { + let index = self.index_of(relation, name)?; Ok(self.columns[index].clone()) } @@ -61,12 +66,16 @@ impl Schema { } /// Find the index of the column with the given name. - pub fn index_of(&self, name: &str) -> BustubxResult { + pub fn index_of(&self, relation: Option<&TableReference>, name: &str) -> BustubxResult { let (idx, _) = self .columns .iter() .enumerate() - .find(|(_, col)| &col.name == name) + .find(|(_, col)| match (relation, &col.relation) { + (Some(rel), Some(col_rel)) => rel.resolved_eq(col_rel) && name == &col.name, + (Some(rel), None) => false, + (None, Some(_)) | (None, None) => name == &col.name, + }) .ok_or_else(|| BustubxError::Plan(format!("Unable to get column named \"{name}\"")))?; Ok(idx) } diff --git a/bustubx/src/common/table_ref.rs b/bustubx/src/common/table_ref.rs index af082da..dc71bd5 100644 --- a/bustubx/src/common/table_ref.rs +++ b/bustubx/src/common/table_ref.rs @@ -59,6 +59,24 @@ impl TableReference { _ => None, } } + + pub fn resolved_eq(&self, other: &Self) -> bool { + match self { + TableReference::Bare { table } => table == other.table(), + TableReference::Partial { schema, table } => { + table == other.table() && other.schema().map_or(true, |s| s == schema) + } + TableReference::Full { + catalog, + schema, + table, + } => { + table == other.table() + && other.schema().map_or(true, |s| s == schema) + && other.catalog().map_or(true, |c| c == catalog) + } + } + } } impl std::fmt::Display for TableReference { diff --git a/bustubx/src/expression/column.rs b/bustubx/src/expression/column.rs index 5b41b1f..f84e274 100644 --- a/bustubx/src/expression/column.rs +++ b/bustubx/src/expression/column.rs @@ -2,7 +2,7 @@ use crate::catalog::Schema; use crate::catalog::{Column, DataType}; use crate::common::ScalarValue; use crate::common::TableReference; -use crate::error::{BustubxError, BustubxResult}; +use crate::error::{BustubxResult}; use crate::expression::ExprTrait; use crate::storage::Tuple; @@ -17,25 +17,29 @@ pub struct ColumnExpr { impl ExprTrait for ColumnExpr { fn data_type(&self, input_schema: &Schema) -> BustubxResult { - let column = input_schema.column_with_name(&self.name)?; + let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?; Ok(column.data_type) } fn nullable(&self, input_schema: &Schema) -> BustubxResult { - let column = input_schema.column_with_name(&self.name)?; + let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?; Ok(column.nullable) } fn evaluate(&self, tuple: &Tuple) -> BustubxResult { - tuple.value_by_name(&self.name).cloned() + tuple + .value_by_name(self.relation.as_ref(), &self.name) + .cloned() } fn to_column(&self, input_schema: &Schema) -> BustubxResult { + let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?; Ok(Column::new( self.name.clone(), self.data_type(input_schema)?, self.nullable(input_schema)?, - )) + ) + .with_relation(self.relation.clone().or(column.relation.clone()))) } } diff --git a/bustubx/src/planner/logical_planner/plan_create_table.rs b/bustubx/src/planner/logical_planner/plan_create_table.rs index ad56588..baa3038 100644 --- a/bustubx/src/planner/logical_planner/plan_create_table.rs +++ b/bustubx/src/planner/logical_planner/plan_create_table.rs @@ -14,11 +14,14 @@ impl<'a> LogicalPlanner<'a> { let name = self.bind_table_name(name)?; let mut columns = vec![]; for col_def in column_defs { - columns.push(Column::new( - col_def.name.value.clone(), - (&col_def.data_type).try_into()?, - false, - )) + columns.push( + Column::new( + col_def.name.value.clone(), + (&col_def.data_type).try_into()?, + false, + ) + .with_relation(Some(name.clone())), + ) } Ok(LogicalPlan::CreateTable(CreateTable { name, columns })) } diff --git a/bustubx/src/planner/logical_planner/plan_insert.rs b/bustubx/src/planner/logical_planner/plan_insert.rs index cd4984f..b1d6eea 100644 --- a/bustubx/src/planner/logical_planner/plan_insert.rs +++ b/bustubx/src/planner/logical_planner/plan_insert.rs @@ -32,7 +32,7 @@ impl<'a> LogicalPlanner<'a> { .collect(); let indices = columns .iter() - .map(|name| table_schema.index_of(name.as_str())) + .map(|name| table_schema.index_of(Some(&table), name.as_str())) .collect::>>()?; let projected_schema = table_schema.project(&indices)?; projected_schema diff --git a/bustubx/src/planner/logical_planner/plan_set_expr.rs b/bustubx/src/planner/logical_planner/plan_set_expr.rs index 72b2b3c..d100097 100644 --- a/bustubx/src/planner/logical_planner/plan_set_expr.rs +++ b/bustubx/src/planner/logical_planner/plan_set_expr.rs @@ -49,7 +49,7 @@ impl LogicalPlanner<'_> { .iter() .map(|col| { Expr::Column(ColumnExpr { - relation: None, + relation: col.relation.clone(), name: col.name.clone(), }) }) diff --git a/bustubx/src/storage/tuple.rs b/bustubx/src/storage/tuple.rs index 6c3480c..a037b33 100644 --- a/bustubx/src/storage/tuple.rs +++ b/bustubx/src/storage/tuple.rs @@ -1,5 +1,5 @@ use crate::catalog::{ColumnRef, SchemaRef}; -use crate::common::TransactionId; +use crate::common::{TableReference, TransactionId}; use crate::{catalog::Schema, common::ScalarValue, BustubxError, BustubxResult}; use std::sync::Arc; @@ -74,8 +74,12 @@ impl Tuple { index, self ))) } - pub fn value_by_name(&self, name: &str) -> BustubxResult<&ScalarValue> { - let idx = self.schema.index_of(name)?; + pub fn value_by_name( + &self, + relation: Option<&TableReference>, + name: &str, + ) -> BustubxResult<&ScalarValue> { + let idx = self.schema.index_of(relation, name)?; self.value(idx) } diff --git a/tests/sqllogictest/slt/_join.slt b/tests/sqllogictest/slt/join.slt similarity index 100% rename from tests/sqllogictest/slt/_join.slt rename to tests/sqllogictest/slt/join.slt diff --git a/tests/sqllogictest/slt/select.slt b/tests/sqllogictest/slt/select.slt index e245198..7791728 100644 --- a/tests/sqllogictest/slt/select.slt +++ b/tests/sqllogictest/slt/select.slt @@ -5,12 +5,19 @@ statement ok insert into t1 values (1, 1), (2, 3), (5, 4) query II rowsort -select a, b from t1 +select * from t1 ---- 1 1 2 3 5 4 +query II rowsort +select b from t1 +---- +1 +3 +4 + query I select 1 ----