use std::fmt::Display;
use datafusion_sql::parser::Statement as DfStatement;
use sqlparser::ast::Statement as SpStatement;
use sqlparser_derive::{Visit, VisitMut};
use crate::error::{ConvertToDfStatementSnafu, Error};
use crate::statements::admin::Admin;
use crate::statements::alter::AlterTable;
use crate::statements::create::{
CreateDatabase, CreateExternalTable, CreateFlow, CreateTable, CreateTableLike, CreateView,
};
use crate::statements::delete::Delete;
use crate::statements::describe::DescribeTable;
use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
use crate::statements::explain::Explain;
use crate::statements::insert::Insert;
use crate::statements::query::Query;
use crate::statements::set_variables::SetVariables;
use crate::statements::show::{
ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowStatus, ShowTableStatus, ShowTables,
ShowVariables, ShowViews,
};
use crate::statements::tql::Tql;
use crate::statements::truncate::TruncateTable;
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
pub enum Statement {
Query(Box<Query>),
Insert(Box<Insert>),
Delete(Box<Delete>),
CreateTable(CreateTable),
CreateExternalTable(CreateExternalTable),
CreateTableLike(CreateTableLike),
CreateFlow(CreateFlow),
CreateView(CreateView),
DropTable(DropTable),
DropDatabase(DropDatabase),
DropFlow(DropFlow),
DropView(DropView),
CreateDatabase(CreateDatabase),
Alter(AlterTable),
ShowDatabases(ShowDatabases),
ShowTables(ShowTables),
ShowTableStatus(ShowTableStatus),
ShowColumns(ShowColumns),
ShowCharset(ShowKind),
ShowCollation(ShowKind),
ShowIndex(ShowIndex),
ShowCreateDatabase(ShowCreateDatabase),
ShowCreateTable(ShowCreateTable),
ShowCreateFlow(ShowCreateFlow),
ShowFlows(ShowFlows),
ShowCreateView(ShowCreateView),
ShowStatus(ShowStatus),
ShowViews(ShowViews),
DescribeTable(DescribeTable),
Explain(Explain),
Copy(crate::statements::copy::Copy),
Tql(Tql),
TruncateTable(TruncateTable),
SetVariables(SetVariables),
ShowVariables(ShowVariables),
Use(String),
Admin(Admin),
}
impl Display for Statement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Statement::Query(s) => s.inner.fmt(f),
Statement::Insert(s) => s.inner.fmt(f),
Statement::Delete(s) => s.inner.fmt(f),
Statement::CreateTable(s) => s.fmt(f),
Statement::CreateExternalTable(s) => s.fmt(f),
Statement::CreateTableLike(s) => s.fmt(f),
Statement::CreateFlow(s) => s.fmt(f),
Statement::DropFlow(s) => s.fmt(f),
Statement::DropTable(s) => s.fmt(f),
Statement::DropDatabase(s) => s.fmt(f),
Statement::DropView(s) => s.fmt(f),
Statement::CreateDatabase(s) => s.fmt(f),
Statement::Alter(s) => s.fmt(f),
Statement::ShowDatabases(s) => s.fmt(f),
Statement::ShowTables(s) => s.fmt(f),
Statement::ShowTableStatus(s) => s.fmt(f),
Statement::ShowColumns(s) => s.fmt(f),
Statement::ShowIndex(s) => s.fmt(f),
Statement::ShowCreateTable(s) => s.fmt(f),
Statement::ShowCreateFlow(s) => s.fmt(f),
Statement::ShowFlows(s) => s.fmt(f),
Statement::ShowCreateDatabase(s) => s.fmt(f),
Statement::ShowCreateView(s) => s.fmt(f),
Statement::ShowViews(s) => s.fmt(f),
Statement::ShowStatus(s) => s.fmt(f),
Statement::DescribeTable(s) => s.fmt(f),
Statement::Explain(s) => s.fmt(f),
Statement::Copy(s) => s.fmt(f),
Statement::Tql(s) => s.fmt(f),
Statement::TruncateTable(s) => s.fmt(f),
Statement::SetVariables(s) => s.fmt(f),
Statement::ShowVariables(s) => s.fmt(f),
Statement::ShowCharset(kind) => {
write!(f, "SHOW CHARSET {kind}")
}
Statement::ShowCollation(kind) => {
write!(f, "SHOW COLLATION {kind}")
}
Statement::CreateView(s) => s.fmt(f),
Statement::Use(s) => s.fmt(f),
Statement::Admin(admin) => admin.fmt(f),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Hint {
pub error_code: Option<u16>,
pub comment: String,
pub prefix: String,
}
impl TryFrom<&Statement> for DfStatement {
type Error = Error;
fn try_from(s: &Statement) -> Result<Self, Self::Error> {
let s = match s {
Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
Statement::Explain(explain) => explain.inner.clone(),
Statement::Insert(insert) => insert.inner.clone(),
Statement::Delete(delete) => delete.inner.clone(),
_ => {
return ConvertToDfStatementSnafu {
statement: format!("{s:?}"),
}
.fail();
}
};
Ok(DfStatement::Statement(Box::new(s.into())))
}
}