Skip to content

Commit

Permalink
support add column
Browse files Browse the repository at this point in the history
  • Loading branch information
guojidan committed Nov 27, 2023
1 parent 0edc879 commit 8b54b7c
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 15 deletions.
15 changes: 7 additions & 8 deletions src/binder/alter_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ use std::sync::Arc;

use super::Binder;
use crate::binder::{lower_case_name, split_name, BindError};
use crate::catalog::ColumnCatalog;
use crate::planner::operator::alter_table::{AddColumn, AlterTableOperator};
use crate::planner::operator::scan::ScanOperator;
use crate::planner::operator::Operator;
use crate::planner::LogicalPlan;
use crate::planner::operator::scan::ScanOperator;
use crate::storage::Transaction;

impl<'a, T: Transaction> Binder<'a, T> {
Expand All @@ -27,24 +26,24 @@ impl<'a, T: Transaction> Binder<'a, T> {
if_not_exists,
column_def,
} => {
if let Some(table) = self.context.table(&table_name) {
let plan = ScanOperator::new(table_name.clone(), table);
if let Some(table) = self.context.table(table_name.clone()) {
let plan = ScanOperator::build(table_name.clone(), table);

LogicalPlan {
operator: Operator::AlterTable(AlterTableOperator::AddColumn(AddColumn {
table_name,
if_not_exists: *if_not_exists,
column: ColumnCatalog::from(column_def.clone()),
column: self.bind_column(column_def)?,
})),
childrens: vec![plan],
}
} else {
return Err(BindError::InvalidTable(format!(
"not found table {}",
table_name
)))
)));
}
},
}
AlterTableOperation::DropColumn {
column_name: _,
if_exists: _,
Expand Down
2 changes: 1 addition & 1 deletion src/binder/create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
Ok(plan)
}

fn bind_column(&mut self, column_def: &ColumnDef) -> Result<ColumnCatalog, BindError> {
pub fn bind_column(&mut self, column_def: &ColumnDef) -> Result<ColumnCatalog, BindError> {
let column_name = column_def.name.to_string();
let mut column_desc = ColumnDesc::new(
LogicalType::try_from(column_def.data_type.clone())?,
Expand Down
25 changes: 25 additions & 0 deletions src/execution/executor/ddl/alter_table.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use crate::execution::executor::BoxedExecutor;
use crate::planner::operator::alter_table::AddColumn;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::{execution::ExecutorError, types::tuple_builder::TupleBuilder};
use futures_async_stream::try_stream;
use std::cell::RefCell;
use std::ops::Deref;
use std::sync::Arc;

use crate::{
execution::executor::Executor, planner::operator::alter_table::AlterTableOperator,
Expand Down Expand Up @@ -30,6 +34,27 @@ impl AlterTable {
#[try_stream(boxed, ok = Tuple, error = ExecutorError)]
async fn _execute<T: Transaction>(self, transaction: &mut T) {
let _ = transaction.alter_table(&self.op)?;

if let AlterTableOperator::AddColumn(AddColumn {
table_name, column, ..
}) = &self.op
{
#[for_await]
for tuple in self.input {
let mut tuple: Tuple = tuple?;
let is_overwrite = true;

tuple.columns.push(Arc::new(column.clone()));
if let Some(value) = column.default_value() {
tuple.values.push(Arc::new(value.deref().clone()));
} else {
tuple.values.push(Arc::new(DataValue::Null));
}

transaction.append(table_name, tuple, is_overwrite)?;
}
}

let tuple_builder = TupleBuilder::new_result();
let tuple = tuple_builder.push_result("ALTER TABLE SUCCESS", "1")?;

Expand Down
2 changes: 1 addition & 1 deletion src/execution/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub fn build<T: Transaction>(plan: LogicalPlan, transaction: &RefCell<T>) -> Box
Operator::AlterTable(op) => {
let input = build(childrens.remove(0), transaction);
AlterTable::from((op, input)).execute(transaction)
},
}
Operator::CreateTable(op) => CreateTable::from(op).execute(transaction),
Operator::DropTable(op) => DropTable::from(op).execute(transaction),
Operator::Truncate(op) => Truncate::from(op).execute(transaction),
Expand Down
11 changes: 6 additions & 5 deletions src/storage/kip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl Transaction for KipTransaction {
Ok(())
}

fn delete(&mut self, table_name: &str, tuple_id: TupleId) -> Result<(), StorageError> {
fn delete(&mut self, table_name: &String, tuple_id: TupleId) -> Result<(), StorageError> {
let key = TableCodec::encode_tuple_key(table_name, &tuple_id)?;
self.tx.remove(&key)?;

Expand All @@ -171,7 +171,7 @@ impl Transaction for KipTransaction {
}) => {
// we need catalog generate col_id && index_id
// generally catalog is immutable, so do not worry it changed when alter table going on
if let Some(mut catalog) = self.table(table_name).cloned() {
if let Some(mut catalog) = self.table(table_name.clone()).cloned() {
// not yet supported default value
if !column.nullable {
return Err(StorageError::NeedNullAble);
Expand All @@ -180,7 +180,7 @@ impl Transaction for KipTransaction {
for col in catalog.all_columns() {
if col.name() == column.name() {
if *if_not_exists {
return Ok(())
return Ok(());
} else {
return Err(StorageError::DuplicateColumn);
}
Expand All @@ -195,21 +195,22 @@ impl Transaction for KipTransaction {
column_ids: vec![col_id],
name: format!("uk_{}", column.name()),
is_unique: true,
is_primary: false,
};
let meta_ref = catalog.add_index_meta(meta);
let (key, value) = TableCodec::encode_index_meta(table_name, meta_ref)?;
self.tx.set(key, value);
}

let column = catalog.get_column_by_id(&col_id).unwrap();
let (key, value) = TableCodec::encode_column(column)?;
let (key, value) = TableCodec::encode_column(&table_name, column)?;
self.tx.set(key, value);

Ok(())
} else {
return Err(StorageError::TableNotFound);
}
},
}
AlterTableOperator::DropColumn => todo!(),
AlterTableOperator::DropPrimaryKey => todo!(),
AlterTableOperator::RenameColumn => todo!(),
Expand Down
19 changes: 19 additions & 0 deletions tests/slt/alter_table.slt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
statement ok
create table alter_table(id int primary key, v1 int)

statement ok
insert into alter_table values (1,1), (2,2), (3,3), (4,4)

statement ok
alter table alter_table add column da int null

query IIII rowsort
select * from alter_table
----
1 1 null
2 2 null
3 3 null
4 4 null

statement ok
drop table alter_table

0 comments on commit 8b54b7c

Please sign in to comment.