use crate::{
ast::{SelectItem, SelectStmt, TableRef},
binder::{BindError, Binder, bound::BoundSelectStmt},
common::symbol::Symbol,
};
impl<'c> Binder<'c> {
pub fn bind_select(
&self,
db: Symbol,
default_schema: Symbol,
stmt: SelectStmt,
) -> Result<BoundSelectStmt, BindError> {
if stmt.modifier.is_some()
|| !stmt.joins.is_empty()
|| stmt.where_.is_some()
|| !stmt.group_by.is_empty()
|| stmt.having.is_some()
|| !stmt.order_by.is_empty()
|| stmt.limit.is_some()
|| stmt.offset.is_some()
|| !stmt.ctes.is_empty()
|| stmt.set_op.is_some()
{
return Err(BindError::UnsupportedSelect);
}
if stmt.from.len() != 1 {
return Err(BindError::UnsupportedSelect);
}
let table_ref = stmt.from.into_iter().next().unwrap();
let table_name = match table_ref {
TableRef::Named { name, .. } => name,
_ => return Err(BindError::UnsupportedSelect),
};
if stmt.columns.len() != 1 {
return Err(BindError::UnsupportedSelect);
}
match &stmt.columns[0] {
SelectItem::Wildcard => {}
_ => return Err(BindError::UnsupportedSelect),
}
let (schema, table) = table_name.resolve_schema_table(default_schema);
let table_entry = self
.catalog
.get_table(db, schema, table)
.map_err(|_| BindError::TableNotFound(table))?;
let columns = table_entry.columns.clone();
Ok(BoundSelectStmt {
db,
schema,
table,
columns,
})
}
}