Skip to content

Commit

Permalink
feat: support AS (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
KKould authored Feb 7, 2024
1 parent c6d0536 commit b11a8c9
Show file tree
Hide file tree
Showing 33 changed files with 285 additions and 416 deletions.
2 changes: 1 addition & 1 deletion src/binder/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'a, T: Transaction> Binder<'a, T> {

if !group_raw_exprs.iter().contains(expr) {
return Err(DatabaseError::AggMiss(format!(
"{:?} must appear in the GROUP BY clause or be used in an aggregate function",
"`{}` must appear in the GROUP BY clause or be used in an aggregate function",
expr
)));
}
Expand Down
4 changes: 2 additions & 2 deletions src/binder/alter_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use sqlparser::ast::{AlterTableOperation, ObjectName};
use std::sync::Arc;

use super::{is_valid_identifier, Binder};
use crate::binder::{lower_case_name, split_name};
use crate::binder::lower_case_name;
use crate::errors::DatabaseError;
use crate::planner::operator::alter_table::add_column::AddColumnOperator;
use crate::planner::operator::alter_table::drop_column::DropColumnOperator;
Expand All @@ -18,7 +18,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
name: &ObjectName,
operation: &AlterTableOperation,
) -> Result<LogicalPlan, DatabaseError> {
let table_name: Arc<String> = Arc::new(split_name(&lower_case_name(name))?.to_string());
let table_name: Arc<String> = Arc::new(lower_case_name(name)?);

if let Some(table) = self.context.table(table_name.clone()) {
let plan = match operation {
Expand Down
6 changes: 2 additions & 4 deletions src/binder/analyze.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::binder::{lower_case_name, split_name, Binder};
use crate::binder::{lower_case_name, Binder};
use crate::errors::DatabaseError;
use crate::planner::operator::analyze::AnalyzeOperator;
use crate::planner::operator::scan::ScanOperator;
Expand All @@ -11,9 +11,7 @@ use std::sync::Arc;

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

let table_catalog = self.context.table_and_bind(table_name.clone(), None)?;
let columns = table_catalog
Expand Down
8 changes: 3 additions & 5 deletions src/binder/create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::HashSet;
use std::sync::Arc;

use super::{is_valid_identifier, Binder};
use crate::binder::{lower_case_name, split_name};
use crate::binder::lower_case_name;
use crate::catalog::{ColumnCatalog, ColumnDesc};
use crate::errors::DatabaseError;
use crate::expression::ScalarExpression;
Expand All @@ -24,9 +24,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
constraints: &[TableConstraint],
if_not_exists: bool,
) -> Result<LogicalPlan, DatabaseError> {
let name = lower_case_name(name);
let name = split_name(&name)?;
let table_name = Arc::new(name.to_string());
let table_name = Arc::new(lower_case_name(name)?);

if !is_valid_identifier(&table_name) {
return Err(DatabaseError::InvalidTable(
Expand Down Expand Up @@ -132,7 +130,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
}
}

Ok(ColumnCatalog::new(column_name, nullable, column_desc, None))
Ok(ColumnCatalog::new(column_name, nullable, column_desc))
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/binder/delete.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::binder::{lower_case_name, split_name, Binder};
use crate::binder::{lower_case_name, Binder};
use crate::errors::DatabaseError;
use crate::planner::operator::delete::DeleteOperator;
use crate::planner::operator::scan::ScanOperator;
Expand All @@ -15,9 +15,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
selection: &Option<Expr>,
) -> Result<LogicalPlan, DatabaseError> {
if let TableFactor::Table { name, alias, .. } = &from.relation {
let name = lower_case_name(name);
let name = split_name(&name)?;
let table_name = Arc::new(name.to_string());
let table_name = Arc::new(lower_case_name(name)?);

let table_catalog = self.context.table_and_bind(table_name.clone(), None)?;
let primary_key_column = table_catalog
Expand All @@ -29,7 +27,7 @@ impl<'a, T: Transaction> Binder<'a, T> {

if let Some(alias) = alias {
self.context
.add_table_alias(alias.to_string(), table_name.clone())?;
.add_table_alias(alias.to_string(), table_name.clone());
}

if let Some(predicate) = selection {
Expand Down
6 changes: 2 additions & 4 deletions src/binder/describe.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::binder::{lower_case_name, split_name, Binder};
use crate::binder::{lower_case_name, Binder};
use crate::errors::DatabaseError;
use crate::planner::operator::describe::DescribeOperator;
use crate::planner::operator::Operator;
Expand All @@ -12,9 +12,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
&mut self,
name: &ObjectName,
) -> Result<LogicalPlan, DatabaseError> {
let name = lower_case_name(&name);
let name = split_name(&name)?;
let table_name = Arc::new(name.to_string());
let table_name = Arc::new(lower_case_name(name)?);

Ok(LogicalPlan {
operator: Operator::Describe(DescribeOperator { table_name }),
Expand Down
6 changes: 2 additions & 4 deletions src/binder/drop_table.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::binder::{lower_case_name, split_name, Binder};
use crate::binder::{lower_case_name, Binder};
use crate::errors::DatabaseError;
use crate::planner::operator::drop_table::DropTableOperator;
use crate::planner::operator::Operator;
Expand All @@ -13,9 +13,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
name: &ObjectName,
if_exists: &bool,
) -> Result<LogicalPlan, DatabaseError> {
let name = lower_case_name(name);
let name = split_name(&name)?;
let table_name = Arc::new(name.to_string());
let table_name = Arc::new(lower_case_name(name)?);

let plan = LogicalPlan {
operator: Operator::DropTable(DropTableOperator {
Expand Down
51 changes: 25 additions & 26 deletions src/binder/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@ use sqlparser::ast::{
use std::slice;
use std::sync::Arc;

use super::Binder;
use super::{lower_ident, Binder};
use crate::expression::ScalarExpression;
use crate::storage::Transaction;
use crate::types::value::DataValue;
use crate::types::LogicalType;

macro_rules! try_alias {
($context:expr, $column_name:expr) => {
if let Some(expr) = $context.expr_aliases.get(&$column_name) {
return Ok(ScalarExpression::Alias {
expr: Box::new(expr.clone()),
alias: $column_name,
});
}
};
}

impl<'a, T: Transaction> Binder<'a, T> {
pub(crate) fn bind_expr(&mut self, expr: &Expr) -> Result<ScalarExpression, DatabaseError> {
match expr {
Expand Down Expand Up @@ -76,16 +87,11 @@ impl<'a, T: Transaction> Binder<'a, T> {
pub fn bind_column_ref_from_identifiers(
&mut self,
idents: &[Ident],
bind_table_name: Option<&String>,
bind_table_name: Option<String>,
) -> Result<ScalarExpression, DatabaseError> {
let idents = idents
.iter()
.map(|ident| Ident::new(ident.value.to_lowercase()))
.collect_vec();
let (_schema_name, table_name, column_name) = match idents.as_slice() {
[column] => (None, None, &column.value),
[table, column] => (None, Some(&table.value), &column.value),
[schema, table, column] => (Some(&schema.value), Some(&table.value), &column.value),
let (table_name, column_name) = match idents {
[column] => (None, lower_ident(column)),
[table, column] => (Some(lower_ident(table)), lower_ident(column)),
_ => {
return Err(DatabaseError::InvalidColumn(
idents
Expand All @@ -96,38 +102,31 @@ impl<'a, T: Transaction> Binder<'a, T> {
))
}
};

if let Some(table) = table_name.or(bind_table_name) {
try_alias!(self.context, column_name);
let table_catalog = self
.context
.table(Arc::new(table.clone()))
.ok_or_else(|| DatabaseError::InvalidTable(table.to_string()))?;
.ok_or_else(|| DatabaseError::TableNotFound)?;

let column_catalog = table_catalog
.get_column_by_name(column_name)
.ok_or_else(|| DatabaseError::InvalidColumn(column_name.to_string()))?;
.get_column_by_name(&column_name)
.ok_or_else(|| DatabaseError::NotFound("column", column_name))?;
Ok(ScalarExpression::ColumnRef(column_catalog.clone()))
} else {
try_alias!(self.context, column_name);
// handle col syntax
let mut got_column = None;
for (table_catalog, _) in self.context.bind_table.values() {
if let Some(column_catalog) = table_catalog.get_column_by_name(column_name) {
if got_column.is_some() {
return Err(DatabaseError::InvalidColumn(column_name.to_string()));
}
if let Some(column_catalog) = table_catalog.get_column_by_name(&column_name) {
got_column = Some(column_catalog);
}
}
if got_column.is_none() {
if let Some(expr) = self.context.aliases.get(column_name) {
return Ok(ScalarExpression::Alias {
expr: Box::new(expr.clone()),
alias: column_name.clone(),
});
if got_column.is_some() {
break;
}
}
let column_catalog =
got_column.ok_or_else(|| DatabaseError::InvalidColumn(column_name.to_string()))?;
got_column.ok_or_else(|| DatabaseError::NotFound("column", column_name))?;
Ok(ScalarExpression::ColumnRef(column_catalog.clone()))
}
}
Expand Down
11 changes: 4 additions & 7 deletions src/binder/insert.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::binder::{lower_case_name, split_name, Binder};
use crate::binder::{lower_case_name, Binder};
use crate::catalog::ColumnRef;
use crate::errors::DatabaseError;
use crate::expression::value_compute::unary_op;
Expand All @@ -16,14 +16,12 @@ use std::sync::Arc;
impl<'a, T: Transaction> Binder<'a, T> {
pub(crate) fn bind_insert(
&mut self,
name: ObjectName,
name: &ObjectName,
idents: &[Ident],
expr_rows: &Vec<Vec<Expr>>,
is_overwrite: bool,
) -> Result<LogicalPlan, DatabaseError> {
let name = lower_case_name(&name);
let name = split_name(&name)?;
let table_name = Arc::new(name.to_string());
let table_name = Arc::new(lower_case_name(name)?);

if let Some(table) = self.context.table(table_name.clone()) {
let mut columns = Vec::new();
Expand All @@ -35,11 +33,10 @@ impl<'a, T: Transaction> Binder<'a, T> {
return Err(DatabaseError::ValuesLenMismatch(columns.len(), values_len));
}
} else {
let bind_table_name = Some(table_name.to_string());
for ident in idents {
match self.bind_column_ref_from_identifiers(
slice::from_ref(ident),
bind_table_name.as_ref(),
Some(table_name.to_string()),
)? {
ScalarExpression::ColumnRef(catalog) => columns.push(catalog),
_ => unreachable!(),
Expand Down
Loading

0 comments on commit b11a8c9

Please sign in to comment.