1use std::fmt::Display;
16
17use datafusion_sql::parser::Statement as DfStatement;
18use serde::Serialize;
19use sqlparser::ast::Statement as SpStatement;
20use sqlparser_derive::{Visit, VisitMut};
21
22use crate::error::{ConvertToDfStatementSnafu, Error};
23use crate::statements::admin::Admin;
24use crate::statements::alter::{AlterDatabase, AlterTable};
25use crate::statements::copy::Copy;
26use crate::statements::create::{
27    CreateDatabase, CreateExternalTable, CreateFlow, CreateTable, CreateTableLike, CreateView,
28};
29use crate::statements::cursor::{CloseCursor, DeclareCursor, FetchCursor};
30use crate::statements::delete::Delete;
31use crate::statements::describe::DescribeTable;
32use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
33use crate::statements::explain::ExplainStatement;
34use crate::statements::insert::Insert;
35use crate::statements::kill::Kill;
36use crate::statements::query::Query;
37use crate::statements::set_variables::SetVariables;
38use crate::statements::show::{
39    ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
40    ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowProcessList, ShowRegion, ShowSearchPath,
41    ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
42};
43use crate::statements::tql::Tql;
44use crate::statements::truncate::TruncateTable;
45
46#[allow(clippy::large_enum_variant)]
48#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
49pub enum Statement {
50    Query(Box<Query>),
52    Insert(Box<Insert>),
54    Delete(Box<Delete>),
56    CreateTable(CreateTable),
58    CreateExternalTable(CreateExternalTable),
60    CreateTableLike(CreateTableLike),
62    CreateFlow(CreateFlow),
64    CreateView(CreateView),
66    #[cfg(feature = "enterprise")]
68    CreateTrigger(crate::statements::create::trigger::CreateTrigger),
69    DropTable(DropTable),
71    DropDatabase(DropDatabase),
73    DropFlow(DropFlow),
75    #[cfg(feature = "enterprise")]
77    DropTrigger(crate::statements::drop::trigger::DropTrigger),
78    DropView(DropView),
80    CreateDatabase(CreateDatabase),
82    AlterTable(AlterTable),
84    AlterDatabase(AlterDatabase),
86    #[cfg(feature = "enterprise")]
88    AlterTrigger(crate::statements::alter::trigger::AlterTrigger),
89    ShowDatabases(ShowDatabases),
91    ShowTables(ShowTables),
93    ShowTableStatus(ShowTableStatus),
95    ShowColumns(ShowColumns),
97    ShowCharset(ShowKind),
99    ShowCollation(ShowKind),
101    ShowIndex(ShowIndex),
103    ShowRegion(ShowRegion),
105    ShowCreateDatabase(ShowCreateDatabase),
107    ShowCreateTable(ShowCreateTable),
109    ShowCreateFlow(ShowCreateFlow),
111    #[cfg(feature = "enterprise")]
112    ShowCreateTrigger(crate::statements::show::trigger::ShowCreateTrigger),
113    ShowFlows(ShowFlows),
115    #[cfg(feature = "enterprise")]
117    ShowTriggers(crate::statements::show::trigger::ShowTriggers),
118    ShowCreateView(ShowCreateView),
120    ShowStatus(ShowStatus),
122    ShowSearchPath(ShowSearchPath),
124    ShowViews(ShowViews),
126    DescribeTable(DescribeTable),
128    Explain(Box<ExplainStatement>),
130    Copy(Copy),
132    Tql(Tql),
134    TruncateTable(TruncateTable),
136    SetVariables(SetVariables),
138    ShowVariables(ShowVariables),
140    Use(String),
142    Admin(Admin),
144    DeclareCursor(DeclareCursor),
146    FetchCursor(FetchCursor),
148    CloseCursor(CloseCursor),
150    Kill(Kill),
152    ShowProcesslist(ShowProcessList),
154}
155
156impl Statement {
157    pub fn is_readonly(&self) -> bool {
158        match self {
159            Statement::Query(_)
161            | Statement::ShowDatabases(_)
162            | Statement::ShowTables(_)
163            | Statement::ShowTableStatus(_)
164            | Statement::ShowColumns(_)
165            | Statement::ShowCharset(_)
166            | Statement::ShowCollation(_)
167            | Statement::ShowIndex(_)
168            | Statement::ShowRegion(_)
169            | Statement::ShowCreateDatabase(_)
170            | Statement::ShowCreateTable(_)
171            | Statement::ShowCreateFlow(_)
172            | Statement::ShowFlows(_)
173            | Statement::ShowCreateView(_)
174            | Statement::ShowStatus(_)
175            | Statement::ShowSearchPath(_)
176            | Statement::ShowViews(_)
177            | Statement::DescribeTable(_)
178            | Statement::Explain(_)
179            | Statement::ShowVariables(_)
180            | Statement::ShowProcesslist(_)
181            | Statement::FetchCursor(_)
182            | Statement::Tql(_) => true,
183
184            #[cfg(feature = "enterprise")]
185            Statement::ShowCreateTrigger(_) => true,
186            #[cfg(feature = "enterprise")]
187            Statement::ShowTriggers(_) => true,
188
189            Statement::Insert(_)
191            | Statement::Delete(_)
192            | Statement::CreateTable(_)
193            | Statement::CreateExternalTable(_)
194            | Statement::CreateTableLike(_)
195            | Statement::CreateFlow(_)
196            | Statement::CreateView(_)
197            | Statement::DropTable(_)
198            | Statement::DropDatabase(_)
199            | Statement::DropFlow(_)
200            | Statement::DropView(_)
201            | Statement::CreateDatabase(_)
202            | Statement::AlterTable(_)
203            | Statement::AlterDatabase(_)
204            | Statement::Copy(_)
205            | Statement::TruncateTable(_)
206            | Statement::SetVariables(_)
207            | Statement::Use(_)
208            | Statement::DeclareCursor(_)
209            | Statement::CloseCursor(_)
210            | Statement::Kill(_)
211            | Statement::Admin(_) => false,
212
213            #[cfg(feature = "enterprise")]
214            Statement::AlterTrigger(_) => false,
215
216            #[cfg(feature = "enterprise")]
217            Statement::CreateTrigger(_) | Statement::DropTrigger(_) => false,
218        }
219    }
220}
221
222impl Display for Statement {
223    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224        match self {
225            Statement::Query(s) => s.inner.fmt(f),
226            Statement::Insert(s) => s.inner.fmt(f),
227            Statement::Delete(s) => s.inner.fmt(f),
228            Statement::CreateTable(s) => s.fmt(f),
229            Statement::CreateExternalTable(s) => s.fmt(f),
230            Statement::CreateTableLike(s) => s.fmt(f),
231            Statement::CreateFlow(s) => s.fmt(f),
232            #[cfg(feature = "enterprise")]
233            Statement::CreateTrigger(s) => s.fmt(f),
234            Statement::DropFlow(s) => s.fmt(f),
235            #[cfg(feature = "enterprise")]
236            Statement::DropTrigger(s) => s.fmt(f),
237            Statement::DropTable(s) => s.fmt(f),
238            Statement::DropDatabase(s) => s.fmt(f),
239            Statement::DropView(s) => s.fmt(f),
240            Statement::CreateDatabase(s) => s.fmt(f),
241            Statement::AlterTable(s) => s.fmt(f),
242            Statement::AlterDatabase(s) => s.fmt(f),
243            #[cfg(feature = "enterprise")]
244            Statement::AlterTrigger(s) => s.fmt(f),
245            Statement::ShowDatabases(s) => s.fmt(f),
246            Statement::ShowTables(s) => s.fmt(f),
247            Statement::ShowTableStatus(s) => s.fmt(f),
248            Statement::ShowColumns(s) => s.fmt(f),
249            Statement::ShowIndex(s) => s.fmt(f),
250            Statement::ShowRegion(s) => s.fmt(f),
251            Statement::ShowCreateTable(s) => s.fmt(f),
252            Statement::ShowCreateFlow(s) => s.fmt(f),
253            #[cfg(feature = "enterprise")]
254            Statement::ShowCreateTrigger(s) => s.fmt(f),
255            Statement::ShowFlows(s) => s.fmt(f),
256            #[cfg(feature = "enterprise")]
257            Statement::ShowTriggers(s) => s.fmt(f),
258            Statement::ShowCreateDatabase(s) => s.fmt(f),
259            Statement::ShowCreateView(s) => s.fmt(f),
260            Statement::ShowViews(s) => s.fmt(f),
261            Statement::ShowStatus(s) => s.fmt(f),
262            Statement::ShowSearchPath(s) => s.fmt(f),
263            Statement::DescribeTable(s) => s.fmt(f),
264            Statement::Explain(s) => s.fmt(f),
265            Statement::Copy(s) => s.fmt(f),
266            Statement::Tql(s) => s.fmt(f),
267            Statement::TruncateTable(s) => s.fmt(f),
268            Statement::SetVariables(s) => s.fmt(f),
269            Statement::ShowVariables(s) => s.fmt(f),
270            Statement::ShowCharset(kind) => {
271                write!(f, "SHOW CHARSET {kind}")
272            }
273            Statement::ShowCollation(kind) => {
274                write!(f, "SHOW COLLATION {kind}")
275            }
276            Statement::CreateView(s) => s.fmt(f),
277            Statement::Use(s) => s.fmt(f),
278            Statement::Admin(admin) => admin.fmt(f),
279            Statement::DeclareCursor(s) => s.fmt(f),
280            Statement::FetchCursor(s) => s.fmt(f),
281            Statement::CloseCursor(s) => s.fmt(f),
282            Statement::Kill(k) => k.fmt(f),
283            Statement::ShowProcesslist(s) => s.fmt(f),
284        }
285    }
286}
287
288#[derive(Debug, Clone, PartialEq, Eq)]
292pub struct Hint {
293    pub error_code: Option<u16>,
294    pub comment: String,
295    pub prefix: String,
296}
297
298impl TryFrom<&Statement> for DfStatement {
299    type Error = Error;
300
301    fn try_from(s: &Statement) -> Result<Self, Self::Error> {
302        let s = match s {
303            Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
304            Statement::Insert(insert) => insert.inner.clone(),
305            Statement::Delete(delete) => delete.inner.clone(),
306            _ => {
307                return ConvertToDfStatementSnafu {
308                    statement: format!("{s:?}"),
309                }
310                .fail();
311            }
312        };
313        Ok(DfStatement::Statement(Box::new(s)))
314    }
315}