kip-sql 0.0.1-alpha.8

build the SQL layer of KipDB database
Documentation
use sqlparser::ast::{AlterTableOperation, ObjectName};

use std::sync::Arc;

use super::{is_valid_identifier, Binder};
use crate::binder::{lower_case_name, split_name, BindError};
use crate::planner::operator::alter_table::add_column::AddColumnOperator;
use crate::planner::operator::alter_table::drop_column::DropColumnOperator;
use crate::planner::operator::scan::ScanOperator;
use crate::planner::operator::Operator;
use crate::planner::LogicalPlan;
use crate::storage::Transaction;

impl<'a, T: Transaction> Binder<'a, T> {
    pub(crate) fn bind_alter_table(
        &mut self,
        name: &ObjectName,
        operation: &AlterTableOperation,
    ) -> Result<LogicalPlan, BindError> {
        let table_name: Arc<String> = Arc::new(split_name(&lower_case_name(name))?.to_string());

        if let Some(table) = self.context.table(table_name.clone()) {
            let plan = match operation {
                AlterTableOperation::AddColumn {
                    column_keyword: _,
                    if_not_exists,
                    column_def,
                } => {
                    let plan = ScanOperator::build(table_name.clone(), table);
                    let column = self.bind_column(column_def)?;

                    if !is_valid_identifier(column.name()) {
                        return Err(BindError::InvalidColumn(
                            "illegal column naming".to_string(),
                        ));
                    }
                    LogicalPlan {
                        operator: Operator::AddColumn(AddColumnOperator {
                            table_name,
                            if_not_exists: *if_not_exists,
                            column,
                        }),
                        childrens: vec![plan],
                    }
                }
                AlterTableOperation::DropColumn {
                    column_name,
                    if_exists,
                    ..
                } => {
                    let plan = ScanOperator::build(table_name.clone(), table);
                    let column_name = column_name.value.clone();

                    LogicalPlan {
                        operator: Operator::DropColumn(DropColumnOperator {
                            table_name,
                            if_exists: *if_exists,
                            column_name,
                        }),
                        childrens: vec![plan],
                    }
                }
                AlterTableOperation::DropPrimaryKey => todo!(),
                AlterTableOperation::RenameColumn {
                    old_column_name: _,
                    new_column_name: _,
                } => todo!(),
                AlterTableOperation::RenameTable { table_name: _ } => todo!(),
                AlterTableOperation::ChangeColumn {
                    old_name: _,
                    new_name: _,
                    data_type: _,
                    options: _,
                } => todo!(),
                AlterTableOperation::AlterColumn {
                    column_name: _,
                    op: _,
                } => todo!(),
                _ => todo!(),
            };

            Ok(plan)
        } else {
            Err(BindError::InvalidTable(format!(
                "not found table {}",
                table_name
            )))
        }
    }
}