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;
33#[cfg(feature = "enterprise")]
34use crate::statements::drop::UndropTable;
35use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
36use crate::statements::explain::ExplainStatement;
37use crate::statements::insert::Insert;
38use crate::statements::kill::Kill;
39use crate::statements::query::Query;
40use crate::statements::set_variables::SetVariables;
41use crate::statements::show::{
42 ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
43 ShowDatabases, ShowFlowStatus, ShowFlows, ShowIndex, ShowKind, ShowProcessList, ShowRegion,
44 ShowSearchPath, ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
45};
46use crate::statements::tql::Tql;
47use crate::statements::truncate::TruncateTable;
48
49#[allow(clippy::large_enum_variant)]
51#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
52pub enum Statement {
53 Query(Box<Query>),
55 Insert(Box<Insert>),
57 Delete(Box<Delete>),
59 CreateTable(CreateTable),
61 CreateExternalTable(CreateExternalTable),
63 CreateTableLike(CreateTableLike),
65 CreateFlow(CreateFlow),
67 CreateView(CreateView),
69 #[cfg(feature = "enterprise")]
71 CreateTrigger(crate::statements::create::trigger::CreateTrigger),
72 DropTable(DropTable),
74 #[cfg(feature = "enterprise")]
76 UndropTable(UndropTable),
77 DropDatabase(DropDatabase),
79 DropFlow(DropFlow),
81 #[cfg(feature = "enterprise")]
83 DropTrigger(crate::statements::drop::trigger::DropTrigger),
84 DropView(DropView),
86 CreateDatabase(CreateDatabase),
88 AlterTable(AlterTable),
90 AlterDatabase(AlterDatabase),
92 #[cfg(feature = "enterprise")]
94 AlterTrigger(crate::statements::alter::trigger::AlterTrigger),
95 ShowDatabases(ShowDatabases),
97 ShowTables(ShowTables),
99 ShowTableStatus(ShowTableStatus),
101 ShowColumns(ShowColumns),
103 ShowCharset(ShowKind),
105 ShowCollation(ShowKind),
107 ShowIndex(ShowIndex),
109 ShowRegion(ShowRegion),
111 ShowCreateDatabase(ShowCreateDatabase),
113 ShowCreateTable(ShowCreateTable),
115 ShowCreateFlow(ShowCreateFlow),
117 #[cfg(feature = "enterprise")]
118 ShowCreateTrigger(crate::statements::show::trigger::ShowCreateTrigger),
119 ShowFlows(ShowFlows),
121 ShowFlowStatus(ShowFlowStatus),
123 #[cfg(feature = "enterprise")]
125 ShowTriggers(crate::statements::show::trigger::ShowTriggers),
126 ShowCreateView(ShowCreateView),
128 ShowStatus(ShowStatus),
130 ShowSearchPath(ShowSearchPath),
132 ShowViews(ShowViews),
134 DescribeTable(DescribeTable),
136 Explain(Box<ExplainStatement>),
138 Copy(Copy),
140 Tql(Tql),
142 TruncateTable(TruncateTable),
144 SetVariables(SetVariables),
146 ShowVariables(ShowVariables),
148 Comment(Comment),
150 Use(String),
152 Admin(Admin),
154 DeclareCursor(DeclareCursor),
156 FetchCursor(FetchCursor),
158 CloseCursor(CloseCursor),
160 Kill(Kill),
162 ShowProcesslist(ShowProcessList),
164}
165
166impl Statement {
167 pub fn is_readonly(&self) -> bool {
168 match self {
169 Statement::Query(_)
171 | Statement::ShowDatabases(_)
172 | Statement::ShowTables(_)
173 | Statement::ShowTableStatus(_)
174 | Statement::ShowColumns(_)
175 | Statement::ShowCharset(_)
176 | Statement::ShowCollation(_)
177 | Statement::ShowIndex(_)
178 | Statement::ShowRegion(_)
179 | Statement::ShowCreateDatabase(_)
180 | Statement::ShowCreateTable(_)
181 | Statement::ShowCreateFlow(_)
182 | Statement::ShowFlows(_)
183 | Statement::ShowFlowStatus(_)
184 | Statement::ShowCreateView(_)
185 | Statement::ShowStatus(_)
186 | Statement::ShowSearchPath(_)
187 | Statement::ShowViews(_)
188 | Statement::DescribeTable(_)
189 | Statement::ShowVariables(_)
190 | Statement::ShowProcesslist(_)
191 | Statement::FetchCursor(_)
192 | Statement::Tql(_) => true,
193
194 #[cfg(feature = "enterprise")]
195 Statement::ShowCreateTrigger(_) => true,
196 #[cfg(feature = "enterprise")]
197 Statement::ShowTriggers(_) => true,
198
199 Statement::Explain(explain) => !explain.analyze || explain.statement.is_readonly(),
200
201 Statement::Insert(_)
203 | Statement::Delete(_)
204 | Statement::CreateTable(_)
205 | Statement::CreateExternalTable(_)
206 | Statement::CreateTableLike(_)
207 | Statement::CreateFlow(_)
208 | Statement::CreateView(_)
209 | Statement::DropTable(_)
210 | Statement::DropDatabase(_)
211 | Statement::DropFlow(_)
212 | Statement::DropView(_)
213 | Statement::CreateDatabase(_)
214 | Statement::AlterTable(_)
215 | Statement::AlterDatabase(_)
216 | Statement::Copy(_)
217 | Statement::TruncateTable(_)
218 | Statement::SetVariables(_)
219 | Statement::Comment(_)
220 | Statement::Use(_)
221 | Statement::DeclareCursor(_)
222 | Statement::CloseCursor(_)
223 | Statement::Kill(_)
224 | Statement::Admin(_) => false,
225
226 #[cfg(feature = "enterprise")]
227 Statement::UndropTable(_) => false,
228
229 #[cfg(feature = "enterprise")]
230 Statement::AlterTrigger(_) => false,
231
232 #[cfg(feature = "enterprise")]
233 Statement::CreateTrigger(_) | Statement::DropTrigger(_) => false,
234 }
235 }
236}
237
238impl Display for Statement {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 match self {
241 Statement::Query(s) => s.inner.fmt(f),
242 Statement::Insert(s) => s.inner.fmt(f),
243 Statement::Delete(s) => s.inner.fmt(f),
244 Statement::CreateTable(s) => s.fmt(f),
245 Statement::CreateExternalTable(s) => s.fmt(f),
246 Statement::CreateTableLike(s) => s.fmt(f),
247 Statement::CreateFlow(s) => s.fmt(f),
248 #[cfg(feature = "enterprise")]
249 Statement::CreateTrigger(s) => s.fmt(f),
250 Statement::DropFlow(s) => s.fmt(f),
251 #[cfg(feature = "enterprise")]
252 Statement::DropTrigger(s) => s.fmt(f),
253 Statement::DropTable(s) => s.fmt(f),
254 #[cfg(feature = "enterprise")]
255 Statement::UndropTable(s) => s.fmt(f),
256 Statement::DropDatabase(s) => s.fmt(f),
257 Statement::DropView(s) => s.fmt(f),
258 Statement::CreateDatabase(s) => s.fmt(f),
259 Statement::AlterTable(s) => s.fmt(f),
260 Statement::AlterDatabase(s) => s.fmt(f),
261 #[cfg(feature = "enterprise")]
262 Statement::AlterTrigger(s) => s.fmt(f),
263 Statement::ShowDatabases(s) => s.fmt(f),
264 Statement::ShowTables(s) => s.fmt(f),
265 Statement::ShowTableStatus(s) => s.fmt(f),
266 Statement::ShowColumns(s) => s.fmt(f),
267 Statement::ShowIndex(s) => s.fmt(f),
268 Statement::ShowRegion(s) => s.fmt(f),
269 Statement::ShowCreateTable(s) => s.fmt(f),
270 Statement::ShowCreateFlow(s) => s.fmt(f),
271 #[cfg(feature = "enterprise")]
272 Statement::ShowCreateTrigger(s) => s.fmt(f),
273 Statement::ShowFlows(s) => s.fmt(f),
274 Statement::ShowFlowStatus(s) => s.fmt(f),
275 #[cfg(feature = "enterprise")]
276 Statement::ShowTriggers(s) => s.fmt(f),
277 Statement::ShowCreateDatabase(s) => s.fmt(f),
278 Statement::ShowCreateView(s) => s.fmt(f),
279 Statement::ShowViews(s) => s.fmt(f),
280 Statement::ShowStatus(s) => s.fmt(f),
281 Statement::ShowSearchPath(s) => s.fmt(f),
282 Statement::DescribeTable(s) => s.fmt(f),
283 Statement::Explain(s) => s.fmt(f),
284 Statement::Copy(s) => s.fmt(f),
285 Statement::Tql(s) => s.fmt(f),
286 Statement::TruncateTable(s) => s.fmt(f),
287 Statement::SetVariables(s) => s.fmt(f),
288 Statement::ShowVariables(s) => s.fmt(f),
289 Statement::Comment(s) => s.fmt(f),
290 Statement::ShowCharset(kind) => {
291 write!(f, "SHOW CHARSET {kind}")
292 }
293 Statement::ShowCollation(kind) => {
294 write!(f, "SHOW COLLATION {kind}")
295 }
296 Statement::CreateView(s) => s.fmt(f),
297 Statement::Use(s) => s.fmt(f),
298 Statement::Admin(admin) => admin.fmt(f),
299 Statement::DeclareCursor(s) => s.fmt(f),
300 Statement::FetchCursor(s) => s.fmt(f),
301 Statement::CloseCursor(s) => s.fmt(f),
302 Statement::Kill(k) => k.fmt(f),
303 Statement::ShowProcesslist(s) => s.fmt(f),
304 }
305 }
306}
307
308#[derive(Debug, Clone, PartialEq, Eq)]
312pub struct Hint {
313 pub error_code: Option<u16>,
314 pub comment: String,
315 pub prefix: String,
316}
317
318impl TryFrom<&Statement> for DfStatement {
319 type Error = Error;
320
321 fn try_from(s: &Statement) -> Result<Self, Self::Error> {
322 let s = match s {
323 Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
324 Statement::Insert(insert) => insert.inner.clone(),
325 Statement::Delete(delete) => delete.inner.clone(),
326 _ => {
327 return ConvertToDfStatementSnafu {
328 statement: format!("{s:?}"),
329 }
330 .fail();
331 }
332 };
333 Ok(DfStatement::Statement(Box::new(s)))
334 }
335}