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::comment::Comment;
26use crate::statements::copy::Copy;
27use crate::statements::create::{
28 CreateDatabase, CreateExternalTable, CreateFlow, CreateTable, CreateTableLike, CreateView,
29};
30use crate::statements::cursor::{CloseCursor, DeclareCursor, FetchCursor};
31use crate::statements::delete::Delete;
32use crate::statements::describe::DescribeTable;
33use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
34use crate::statements::explain::ExplainStatement;
35use crate::statements::insert::Insert;
36use crate::statements::kill::Kill;
37use crate::statements::query::Query;
38use crate::statements::set_variables::SetVariables;
39use crate::statements::show::{
40 ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
41 ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowProcessList, ShowRegion, ShowSearchPath,
42 ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
43};
44use crate::statements::tql::Tql;
45use crate::statements::truncate::TruncateTable;
46
47#[allow(clippy::large_enum_variant)]
49#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
50pub enum Statement {
51 Query(Box<Query>),
53 Insert(Box<Insert>),
55 Delete(Box<Delete>),
57 CreateTable(CreateTable),
59 CreateExternalTable(CreateExternalTable),
61 CreateTableLike(CreateTableLike),
63 CreateFlow(CreateFlow),
65 CreateView(CreateView),
67 #[cfg(feature = "enterprise")]
69 CreateTrigger(crate::statements::create::trigger::CreateTrigger),
70 DropTable(DropTable),
72 DropDatabase(DropDatabase),
74 DropFlow(DropFlow),
76 #[cfg(feature = "enterprise")]
78 DropTrigger(crate::statements::drop::trigger::DropTrigger),
79 DropView(DropView),
81 CreateDatabase(CreateDatabase),
83 AlterTable(AlterTable),
85 AlterDatabase(AlterDatabase),
87 #[cfg(feature = "enterprise")]
89 AlterTrigger(crate::statements::alter::trigger::AlterTrigger),
90 ShowDatabases(ShowDatabases),
92 ShowTables(ShowTables),
94 ShowTableStatus(ShowTableStatus),
96 ShowColumns(ShowColumns),
98 ShowCharset(ShowKind),
100 ShowCollation(ShowKind),
102 ShowIndex(ShowIndex),
104 ShowRegion(ShowRegion),
106 ShowCreateDatabase(ShowCreateDatabase),
108 ShowCreateTable(ShowCreateTable),
110 ShowCreateFlow(ShowCreateFlow),
112 #[cfg(feature = "enterprise")]
113 ShowCreateTrigger(crate::statements::show::trigger::ShowCreateTrigger),
114 ShowFlows(ShowFlows),
116 #[cfg(feature = "enterprise")]
118 ShowTriggers(crate::statements::show::trigger::ShowTriggers),
119 ShowCreateView(ShowCreateView),
121 ShowStatus(ShowStatus),
123 ShowSearchPath(ShowSearchPath),
125 ShowViews(ShowViews),
127 DescribeTable(DescribeTable),
129 Explain(Box<ExplainStatement>),
131 Copy(Copy),
133 Tql(Tql),
135 TruncateTable(TruncateTable),
137 SetVariables(SetVariables),
139 ShowVariables(ShowVariables),
141 Comment(Comment),
143 Use(String),
145 Admin(Admin),
147 DeclareCursor(DeclareCursor),
149 FetchCursor(FetchCursor),
151 CloseCursor(CloseCursor),
153 Kill(Kill),
155 ShowProcesslist(ShowProcessList),
157}
158
159impl Statement {
160 pub fn is_readonly(&self) -> bool {
161 match self {
162 Statement::Query(_)
164 | Statement::ShowDatabases(_)
165 | Statement::ShowTables(_)
166 | Statement::ShowTableStatus(_)
167 | Statement::ShowColumns(_)
168 | Statement::ShowCharset(_)
169 | Statement::ShowCollation(_)
170 | Statement::ShowIndex(_)
171 | Statement::ShowRegion(_)
172 | Statement::ShowCreateDatabase(_)
173 | Statement::ShowCreateTable(_)
174 | Statement::ShowCreateFlow(_)
175 | Statement::ShowFlows(_)
176 | Statement::ShowCreateView(_)
177 | Statement::ShowStatus(_)
178 | Statement::ShowSearchPath(_)
179 | Statement::ShowViews(_)
180 | Statement::DescribeTable(_)
181 | Statement::Explain(_)
182 | Statement::ShowVariables(_)
183 | Statement::ShowProcesslist(_)
184 | Statement::FetchCursor(_)
185 | Statement::Tql(_) => true,
186
187 #[cfg(feature = "enterprise")]
188 Statement::ShowCreateTrigger(_) => true,
189 #[cfg(feature = "enterprise")]
190 Statement::ShowTriggers(_) => true,
191
192 Statement::Insert(_)
194 | Statement::Delete(_)
195 | Statement::CreateTable(_)
196 | Statement::CreateExternalTable(_)
197 | Statement::CreateTableLike(_)
198 | Statement::CreateFlow(_)
199 | Statement::CreateView(_)
200 | Statement::DropTable(_)
201 | Statement::DropDatabase(_)
202 | Statement::DropFlow(_)
203 | Statement::DropView(_)
204 | Statement::CreateDatabase(_)
205 | Statement::AlterTable(_)
206 | Statement::AlterDatabase(_)
207 | Statement::Copy(_)
208 | Statement::TruncateTable(_)
209 | Statement::SetVariables(_)
210 | Statement::Comment(_)
211 | Statement::Use(_)
212 | Statement::DeclareCursor(_)
213 | Statement::CloseCursor(_)
214 | Statement::Kill(_)
215 | Statement::Admin(_) => false,
216
217 #[cfg(feature = "enterprise")]
218 Statement::AlterTrigger(_) => false,
219
220 #[cfg(feature = "enterprise")]
221 Statement::CreateTrigger(_) | Statement::DropTrigger(_) => false,
222 }
223 }
224}
225
226impl Display for Statement {
227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228 match self {
229 Statement::Query(s) => s.inner.fmt(f),
230 Statement::Insert(s) => s.inner.fmt(f),
231 Statement::Delete(s) => s.inner.fmt(f),
232 Statement::CreateTable(s) => s.fmt(f),
233 Statement::CreateExternalTable(s) => s.fmt(f),
234 Statement::CreateTableLike(s) => s.fmt(f),
235 Statement::CreateFlow(s) => s.fmt(f),
236 #[cfg(feature = "enterprise")]
237 Statement::CreateTrigger(s) => s.fmt(f),
238 Statement::DropFlow(s) => s.fmt(f),
239 #[cfg(feature = "enterprise")]
240 Statement::DropTrigger(s) => s.fmt(f),
241 Statement::DropTable(s) => s.fmt(f),
242 Statement::DropDatabase(s) => s.fmt(f),
243 Statement::DropView(s) => s.fmt(f),
244 Statement::CreateDatabase(s) => s.fmt(f),
245 Statement::AlterTable(s) => s.fmt(f),
246 Statement::AlterDatabase(s) => s.fmt(f),
247 #[cfg(feature = "enterprise")]
248 Statement::AlterTrigger(s) => s.fmt(f),
249 Statement::ShowDatabases(s) => s.fmt(f),
250 Statement::ShowTables(s) => s.fmt(f),
251 Statement::ShowTableStatus(s) => s.fmt(f),
252 Statement::ShowColumns(s) => s.fmt(f),
253 Statement::ShowIndex(s) => s.fmt(f),
254 Statement::ShowRegion(s) => s.fmt(f),
255 Statement::ShowCreateTable(s) => s.fmt(f),
256 Statement::ShowCreateFlow(s) => s.fmt(f),
257 #[cfg(feature = "enterprise")]
258 Statement::ShowCreateTrigger(s) => s.fmt(f),
259 Statement::ShowFlows(s) => s.fmt(f),
260 #[cfg(feature = "enterprise")]
261 Statement::ShowTriggers(s) => s.fmt(f),
262 Statement::ShowCreateDatabase(s) => s.fmt(f),
263 Statement::ShowCreateView(s) => s.fmt(f),
264 Statement::ShowViews(s) => s.fmt(f),
265 Statement::ShowStatus(s) => s.fmt(f),
266 Statement::ShowSearchPath(s) => s.fmt(f),
267 Statement::DescribeTable(s) => s.fmt(f),
268 Statement::Explain(s) => s.fmt(f),
269 Statement::Copy(s) => s.fmt(f),
270 Statement::Tql(s) => s.fmt(f),
271 Statement::TruncateTable(s) => s.fmt(f),
272 Statement::SetVariables(s) => s.fmt(f),
273 Statement::ShowVariables(s) => s.fmt(f),
274 Statement::Comment(s) => s.fmt(f),
275 Statement::ShowCharset(kind) => {
276 write!(f, "SHOW CHARSET {kind}")
277 }
278 Statement::ShowCollation(kind) => {
279 write!(f, "SHOW COLLATION {kind}")
280 }
281 Statement::CreateView(s) => s.fmt(f),
282 Statement::Use(s) => s.fmt(f),
283 Statement::Admin(admin) => admin.fmt(f),
284 Statement::DeclareCursor(s) => s.fmt(f),
285 Statement::FetchCursor(s) => s.fmt(f),
286 Statement::CloseCursor(s) => s.fmt(f),
287 Statement::Kill(k) => k.fmt(f),
288 Statement::ShowProcesslist(s) => s.fmt(f),
289 }
290 }
291}
292
293#[derive(Debug, Clone, PartialEq, Eq)]
297pub struct Hint {
298 pub error_code: Option<u16>,
299 pub comment: String,
300 pub prefix: String,
301}
302
303impl TryFrom<&Statement> for DfStatement {
304 type Error = Error;
305
306 fn try_from(s: &Statement) -> Result<Self, Self::Error> {
307 let s = match s {
308 Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
309 Statement::Insert(insert) => insert.inner.clone(),
310 Statement::Delete(delete) => delete.inner.clone(),
311 _ => {
312 return ConvertToDfStatementSnafu {
313 statement: format!("{s:?}"),
314 }
315 .fail();
316 }
317 };
318 Ok(DfStatement::Statement(Box::new(s)))
319 }
320}