use glaredb_error::{DbError, Result};
use serde::{Deserialize, Serialize};
use super::{AstParseable, ObjectReference};
use crate::keywords::Keyword;
use crate::meta::{AstMeta, Raw};
use crate::parser::Parser;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum DropType {
Index,
Function,
Table,
View,
Schema,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum DropDependents {
#[default]
Restrict,
Cascade,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DropStatement<T: AstMeta> {
pub drop_type: DropType,
pub if_exists: bool,
pub name: T::ItemReference,
pub deps: Option<DropDependents>,
}
impl AstParseable for DropStatement<Raw> {
fn parse(parser: &mut Parser) -> Result<Self> {
parser.expect_keyword(Keyword::DROP)?;
let drop_type = match parser.next_keyword()? {
Keyword::TABLE => DropType::Table,
Keyword::INDEX => DropType::Index,
Keyword::FUNCTION => DropType::Function,
Keyword::SCHEMA => DropType::Schema,
Keyword::VIEW => DropType::View,
other => {
return Err(DbError::new(format!(
"Got unexpected keyword for drop type: {other}"
)));
}
};
let if_exists = parser.parse_keyword_sequence(&[Keyword::IF, Keyword::EXISTS]);
let name = ObjectReference::parse(parser)?;
let deps = if parser.parse_keyword(Keyword::CASCADE) {
Some(DropDependents::Cascade)
} else if parser.parse_keyword(Keyword::RESTRICT) {
Some(DropDependents::Restrict)
} else {
None
};
Ok(DropStatement {
drop_type,
if_exists,
name,
deps,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::testutil::parse_ast;
#[test]
fn basic() {
let got = parse_ast::<DropStatement<_>>("drop schema my_schema").unwrap();
let expected = DropStatement {
drop_type: DropType::Schema,
if_exists: false,
name: ObjectReference::from_strings(["my_schema"]),
deps: None,
};
assert_eq!(expected, got);
}
#[test]
fn drop_table_cascade() {
let got = parse_ast::<DropStatement<_>>("drop table my_schema.t1 cascade").unwrap();
let expected = DropStatement {
drop_type: DropType::Table,
if_exists: false,
name: ObjectReference::from_strings(["my_schema", "t1"]),
deps: Some(DropDependents::Cascade),
};
assert_eq!(expected, got);
}
}