Skip to content

Commit

Permalink
Support relation in column
Browse files Browse the repository at this point in the history
  • Loading branch information
lewiszlw committed Feb 5, 2024
1 parent 05f685d commit ef15241
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 20 deletions.
3 changes: 3 additions & 0 deletions bustubx/src/catalog/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ use derive_with::With;
use std::sync::Arc;

use crate::catalog::DataType;
use crate::common::TableReference;

pub type ColumnRef = Arc<Column>;

#[derive(Debug, Clone, With)]
pub struct Column {
pub relation: Option<TableReference>,
pub name: String,
pub data_type: DataType,
pub nullable: bool,
Expand All @@ -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,
Expand Down
17 changes: 13 additions & 4 deletions bustubx/src/catalog/schema.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -48,8 +49,12 @@ impl Schema {
}))
}

pub fn column_with_name(&self, name: &str) -> BustubxResult<ColumnRef> {
let index = self.index_of(name)?;
pub fn column_with_name(
&self,
relation: Option<&TableReference>,
name: &str,
) -> BustubxResult<ColumnRef> {
let index = self.index_of(relation, name)?;
Ok(self.columns[index].clone())
}

Expand All @@ -61,12 +66,16 @@ impl Schema {
}

/// Find the index of the column with the given name.
pub fn index_of(&self, name: &str) -> BustubxResult<usize> {
pub fn index_of(&self, relation: Option<&TableReference>, name: &str) -> BustubxResult<usize> {
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)
}
Expand Down
18 changes: 18 additions & 0 deletions bustubx/src/common/table_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
14 changes: 9 additions & 5 deletions bustubx/src/expression/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -17,25 +17,29 @@ pub struct ColumnExpr {

impl ExprTrait for ColumnExpr {
fn data_type(&self, input_schema: &Schema) -> BustubxResult<DataType> {
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<bool> {
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<ScalarValue> {
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<Column> {
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())))
}
}

Expand Down
13 changes: 8 additions & 5 deletions bustubx/src/planner/logical_planner/plan_create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }))
}
Expand Down
2 changes: 1 addition & 1 deletion bustubx/src/planner/logical_planner/plan_insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<BustubxResult<Vec<usize>>>()?;
let projected_schema = table_schema.project(&indices)?;
projected_schema
Expand Down
2 changes: 1 addition & 1 deletion bustubx/src/planner/logical_planner/plan_set_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl LogicalPlanner<'_> {
.iter()
.map(|col| {
Expr::Column(ColumnExpr {
relation: None,
relation: col.relation.clone(),
name: col.name.clone(),
})
})
Expand Down
10 changes: 7 additions & 3 deletions bustubx/src/storage/tuple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::catalog::{ColumnRef, SchemaRef};

Check warning on line 1 in bustubx/src/storage/tuple.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `ColumnRef`
use crate::common::TransactionId;
use crate::common::{TableReference, TransactionId};
use crate::{catalog::Schema, common::ScalarValue, BustubxError, BustubxResult};
use std::sync::Arc;

Expand Down Expand Up @@ -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)
}

Expand Down
File renamed without changes.
9 changes: 8 additions & 1 deletion tests/sqllogictest/slt/select.slt
Original file line number Diff line number Diff line change
Expand Up @@ -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
----
Expand Down

0 comments on commit ef15241

Please sign in to comment.