use crate::{Rule, ast::*, parser::Parser};
use pest::iterators::Pair;
impl Parser for CreateTable {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (temp, pair) = match pair.as_rule() {
Rule::temp => (true, inner.next().unwrap()),
_ => (false, pair),
};
let (if_not_exists, pair) = match pair.as_rule() {
Rule::if_not_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_table = SchemaObject::parse(pair);
let pair = inner.next().unwrap();
let body = CreateTableBody::parse(pair);
Self {
temp,
if_not_exists,
schema_table,
body,
}
}
}
impl Parser for DropTable {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (if_exists, pair) = match pair.as_rule() {
Rule::if_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_table = SchemaObject::parse(pair);
Self {
if_exists,
schema_table,
}
}
}
impl Parser for AlterTable {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let schema_table = SchemaObject::parse(pair);
let pair = inner.next().unwrap();
let action = match pair.as_rule() {
Rule::alter_table_action1 => {
let name = String::parse(pair.into_inner().next().unwrap());
AlterTableAction::RenameTable(name)
}
Rule::alter_table_action2 => {
let mut inner = pair.into_inner();
let old_name = String::parse(inner.next().unwrap());
let new_name = String::parse(inner.next().unwrap());
AlterTableAction::RenameColumn(old_name, new_name)
}
Rule::alter_table_action3 => {
let column_def = ColumnDef::parse(pair.into_inner().next().unwrap());
AlterTableAction::AddColumn(column_def)
}
Rule::alter_table_action4 => {
let name = String::parse(pair.into_inner().next().unwrap());
AlterTableAction::DropColumn(name)
}
rule => panic!("Unexpected rule: {:?}", rule),
};
Self {
schema_table,
action,
}
}
}
impl Parser for ColumnConstraint {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (name, pair) = match pair.as_rule() {
Rule::ident => (Some(String::parse(pair)), inner.next().unwrap()),
_ => (None, pair),
};
let ty = match pair.as_rule() {
Rule::column_constraint1 => {
let mut inner = pair.into_inner();
let pair = inner.next();
let (order, pair) = match pair {
Some(pair) if matches!(pair.as_rule(), Rule::asc | Rule::desc) => {
(pair.as_rule() == Rule::asc, inner.next())
}
_ => (true, pair),
};
let auto_inc = pair.is_some();
ColumnConstraintType::PrimaryKey {
asc: order,
auto_inc,
}
}
Rule::column_constraint2 => ColumnConstraintType::NotNull,
Rule::column_constraint3 => ColumnConstraintType::Unique,
Rule::column_constraint4 => {
let expr_pair = pair.into_inner().next().unwrap();
ColumnConstraintType::Check(Expr::parse(expr_pair))
}
Rule::column_constraint5 => {
let pair = pair.into_inner().next().unwrap();
ColumnConstraintType::Default(Expr::parse(pair))
}
Rule::column_constraint6 => {
let pair = pair.into_inner().next().unwrap();
let foreign_key = ForeignKey::parse(pair);
ColumnConstraintType::ForeignKey(foreign_key)
}
rule => panic!("Unexpected rule: {:?}", rule),
};
Self { name, ty }
}
}
impl Parser for ColumnDef {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let name = String::parse(pair);
let pair = inner.next();
let (col_type, pair) = match pair {
Some(p) if p.as_rule() == Rule::type_name => (Some(TypeName::parse(p)), inner.next()),
_ => (None, pair),
};
let constraints = pair.map_or(vec![], |p| {
p.into_inner().map(|p| ColumnConstraint::parse(p)).collect()
});
Self {
name,
col_type,
constraints,
}
}
}
impl Parser for TableConstraint {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (name, pair) = match pair.as_rule() {
Rule::ident => (Some(String::parse(pair)), inner.next().unwrap()),
_ => (None, pair),
};
let ty = match pair.as_rule() {
Rule::table_constraint1 => TableConstraintType::PrimaryKey,
Rule::table_constraint2 => TableConstraintType::Unique,
rule => panic!("Unexpected rule: {:?}", rule),
};
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let cols = pair.into_inner().map(|p| IndexedColumn::parse(p)).collect();
Self { name, cols, ty }
}
}
impl Parser for IndexedColumn {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let name = inner.next().unwrap().as_str().to_owned();
let asc = inner.next().map_or(true, |p| p.as_rule() == Rule::asc);
Self { name, asc }
}
}
impl Parser for TypeName {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let str = String::parse(pair);
let affinity = if str.contains("int") {
Affinity::Integer
} else if str.contains("char") || str.contains("clob") || str.contains("text") {
Affinity::Text
} else if str.contains("blob") {
Affinity::Blob
} else if str.contains("real") || str.contains("floa") || str.contains("doub") {
Affinity::Real
} else {
Affinity::Numeric };
let size = match (inner.next(), inner.next()) {
(Some(first), Some(second)) => Some(TypeSize::TypeSize(
first.as_str().to_owned(),
second.as_str().to_owned(),
)),
(Some(first), None) => Some(TypeSize::MaxSize(first.as_str().to_owned())),
_ => None,
};
Self { affinity, size }
}
}
impl Parser for CreateView {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (temp, pair) = match pair.as_rule() {
Rule::temp => (true, inner.next().unwrap()),
_ => (false, pair),
};
let (if_not_exists, pair) = match pair.as_rule() {
Rule::if_not_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_view = SchemaObject::parse(pair);
let pair = inner.next().unwrap();
let (cols, pair) = match pair.as_rule() {
Rule::idents => {
let cols: Vec<_> = pair.into_inner().map(|p| String::parse(p)).collect();
(cols, inner.next().unwrap())
}
_ => (vec![], pair),
};
let select = Select::parse(pair);
Self {
temp,
if_not_exists,
schema_view,
cols,
select,
}
}
}
impl Parser for DropView {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (if_exists, pair) = match pair.as_rule() {
Rule::if_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_view = SchemaObject::parse(pair);
Self {
if_exists,
schema_view,
}
}
}
impl Parser for CreateIndex {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (unique, pair) = match pair.as_rule() {
Rule::unique => (true, inner.next().unwrap()),
_ => (false, pair),
};
let (if_not_exists, pair) = match pair.as_rule() {
Rule::if_not_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_index = SchemaObject::parse(pair);
let pair = inner.next().unwrap();
let table_name = pair.as_str().to_owned();
let pair = inner.next().unwrap();
let indexed_cols: Vec<_> = pair.into_inner().map(|p| IndexedColumn::parse(p)).collect();
let pair = inner.next();
let where_cond = pair.map(|p| Expr::parse(p));
Self {
unique,
if_not_exists,
schema_index,
table_name,
indexed_cols,
where_cond,
}
}
}
impl Parser for DropIndex {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (if_exists, pair) = match pair.as_rule() {
Rule::if_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_index = SchemaObject::parse(pair);
Self {
if_exists,
schema_index,
}
}
}
impl Parser for CreateTableBody {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
match pair.as_rule() {
Rule::select => {
let select = Select::parse(pair);
Self::Select(select)
}
Rule::column_defs => {
let cols = pair
.into_inner()
.map(|p| ColumnDef::parse(p))
.collect::<Vec<_>>();
let pair = inner.next().unwrap();
let constraints = pair
.into_inner()
.map(|p| TableConstraint::parse(p))
.collect();
let options: Vec<_> = inner
.map(|p| match p.as_rule() {
Rule::without_rowid => TableOption::WithoutRowid,
Rule::strict => TableOption::Strict,
rule => unreachable!("Unexpected rule: {:?}", rule),
})
.collect();
Self::Columns {
cols,
constraints,
options,
}
}
rule => unreachable!("Unexpected rule: {:?}", rule),
}
}
}
impl Parser for CreateTrigger {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (temp, pair) = match pair.as_rule() {
Rule::temp => (true, inner.next().unwrap()),
_ => (false, pair),
};
let (if_not_exists, pair) = match pair.as_rule() {
Rule::if_not_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_trigger = SchemaObject::parse(pair);
let pair = inner.next().unwrap();
let timing = match pair.as_rule() {
Rule::before => TriggerTiming::Before,
Rule::after => TriggerTiming::After,
Rule::instead => TriggerTiming::InsteadOf,
rule => panic!("Unexpected rule: {:?}", rule),
};
let pair = inner.next().unwrap();
let event = match pair.as_rule() {
Rule::trigger_event1 => TriggerEvent::Delete,
Rule::trigger_event2 => TriggerEvent::Insert,
Rule::trigger_event3 => {
let mut inner = pair.into_inner();
let cols: Vec<_> = inner.next().map_or(vec![], |p| {
p.into_inner().map(|p| String::parse(p)).collect()
});
TriggerEvent::Update(cols)
}
rule => panic!("Unexpected rule: {:?}", rule),
};
let pair = inner.next().unwrap();
let table_name = String::parse(pair);
let pair = inner.next().unwrap();
let (when_cond, pair) = match pair.as_rule() {
Rule::when_clause => {
let expr_pair = pair.into_inner().next().unwrap();
(Some(Expr::parse(expr_pair)), inner.next().unwrap())
}
_ => (None, pair),
};
let mut statements = vec![];
let first = match pair.as_rule() {
Rule::select => Dml::Select(Select::parse(pair)),
Rule::insert => Dml::Insert(Insert::parse(pair)),
Rule::update => Dml::Update(Update::parse(pair)),
Rule::delete => Dml::Delete(Delete::parse(pair)),
_ => panic!("Unexpected rule: {:?}", pair),
};
statements.push(first);
for p in inner {
let stmt = match p.as_rule() {
Rule::select => Dml::Select(Select::parse(p)),
Rule::insert => Dml::Insert(Insert::parse(p)),
Rule::update => Dml::Update(Update::parse(p)),
Rule::delete => Dml::Delete(Delete::parse(p)),
_ => panic!("Unexpected rule: {:?}", p),
};
statements.push(stmt);
}
Self {
temp,
if_not_exists,
schema_trigger,
timing,
event,
table_name,
when_cond,
statements,
}
}
}
impl Parser for DropTrigger {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let (if_exists, pair) = match pair.as_rule() {
Rule::if_exists => (true, inner.next().unwrap()),
_ => (false, pair),
};
let schema_trigger = SchemaObject::parse(pair);
Self {
if_exists,
schema_trigger,
}
}
}
impl Parser for ForeignKey {
fn parse(pair: Pair<Rule>) -> Self {
let mut inner = pair.into_inner();
let pair = inner.next().unwrap();
let schema_table = SchemaObject::parse(pair);
let pair = inner.next();
let cols = pair.map_or(vec![], |p| {
p.into_inner().map(|p| String::parse(p)).collect()
});
Self { schema_table, cols }
}
}