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::Explain;
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 ShowDatabases(ShowDatabases),
88 ShowTables(ShowTables),
90 ShowTableStatus(ShowTableStatus),
92 ShowColumns(ShowColumns),
94 ShowCharset(ShowKind),
96 ShowCollation(ShowKind),
98 ShowIndex(ShowIndex),
100 ShowRegion(ShowRegion),
102 ShowCreateDatabase(ShowCreateDatabase),
104 ShowCreateTable(ShowCreateTable),
106 ShowCreateFlow(ShowCreateFlow),
108 ShowFlows(ShowFlows),
110 #[cfg(feature = "enterprise")]
112 ShowTriggers(crate::statements::show::trigger::ShowTriggers),
113 ShowCreateView(ShowCreateView),
115 ShowStatus(ShowStatus),
117 ShowSearchPath(ShowSearchPath),
119 ShowViews(ShowViews),
121 DescribeTable(DescribeTable),
123 Explain(Explain),
125 Copy(Copy),
127 Tql(Tql),
129 TruncateTable(TruncateTable),
131 SetVariables(SetVariables),
133 ShowVariables(ShowVariables),
135 Use(String),
137 Admin(Admin),
139 DeclareCursor(DeclareCursor),
141 FetchCursor(FetchCursor),
143 CloseCursor(CloseCursor),
145 Kill(Kill),
147 ShowProcesslist(ShowProcessList),
149}
150
151impl Statement {
152 pub fn is_readonly(&self) -> bool {
153 match self {
154 Statement::Query(_)
156 | Statement::ShowDatabases(_)
157 | Statement::ShowTables(_)
158 | Statement::ShowTableStatus(_)
159 | Statement::ShowColumns(_)
160 | Statement::ShowCharset(_)
161 | Statement::ShowCollation(_)
162 | Statement::ShowIndex(_)
163 | Statement::ShowRegion(_)
164 | Statement::ShowCreateDatabase(_)
165 | Statement::ShowCreateTable(_)
166 | Statement::ShowCreateFlow(_)
167 | Statement::ShowFlows(_)
168 | Statement::ShowCreateView(_)
169 | Statement::ShowStatus(_)
170 | Statement::ShowSearchPath(_)
171 | Statement::ShowViews(_)
172 | Statement::DescribeTable(_)
173 | Statement::Explain(_)
174 | Statement::ShowVariables(_)
175 | Statement::ShowProcesslist(_)
176 | Statement::FetchCursor(_)
177 | Statement::Tql(_) => true,
178
179 #[cfg(feature = "enterprise")]
180 Statement::ShowTriggers(_) => true,
181
182 Statement::Insert(_)
184 | Statement::Delete(_)
185 | Statement::CreateTable(_)
186 | Statement::CreateExternalTable(_)
187 | Statement::CreateTableLike(_)
188 | Statement::CreateFlow(_)
189 | Statement::CreateView(_)
190 | Statement::DropTable(_)
191 | Statement::DropDatabase(_)
192 | Statement::DropFlow(_)
193 | Statement::DropView(_)
194 | Statement::CreateDatabase(_)
195 | Statement::AlterTable(_)
196 | Statement::AlterDatabase(_)
197 | Statement::Copy(_)
198 | Statement::TruncateTable(_)
199 | Statement::SetVariables(_)
200 | Statement::Use(_)
201 | Statement::DeclareCursor(_)
202 | Statement::CloseCursor(_)
203 | Statement::Kill(_)
204 | Statement::Admin(_) => false,
205
206 #[cfg(feature = "enterprise")]
207 Statement::CreateTrigger(_) | Statement::DropTrigger(_) => false,
208 }
209 }
210}
211
212impl Display for Statement {
213 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
214 match self {
215 Statement::Query(s) => s.inner.fmt(f),
216 Statement::Insert(s) => s.inner.fmt(f),
217 Statement::Delete(s) => s.inner.fmt(f),
218 Statement::CreateTable(s) => s.fmt(f),
219 Statement::CreateExternalTable(s) => s.fmt(f),
220 Statement::CreateTableLike(s) => s.fmt(f),
221 Statement::CreateFlow(s) => s.fmt(f),
222 #[cfg(feature = "enterprise")]
223 Statement::CreateTrigger(s) => s.fmt(f),
224 Statement::DropFlow(s) => s.fmt(f),
225 #[cfg(feature = "enterprise")]
226 Statement::DropTrigger(s) => s.fmt(f),
227 Statement::DropTable(s) => s.fmt(f),
228 Statement::DropDatabase(s) => s.fmt(f),
229 Statement::DropView(s) => s.fmt(f),
230 Statement::CreateDatabase(s) => s.fmt(f),
231 Statement::AlterTable(s) => s.fmt(f),
232 Statement::AlterDatabase(s) => s.fmt(f),
233 Statement::ShowDatabases(s) => s.fmt(f),
234 Statement::ShowTables(s) => s.fmt(f),
235 Statement::ShowTableStatus(s) => s.fmt(f),
236 Statement::ShowColumns(s) => s.fmt(f),
237 Statement::ShowIndex(s) => s.fmt(f),
238 Statement::ShowRegion(s) => s.fmt(f),
239 Statement::ShowCreateTable(s) => s.fmt(f),
240 Statement::ShowCreateFlow(s) => s.fmt(f),
241 Statement::ShowFlows(s) => s.fmt(f),
242 #[cfg(feature = "enterprise")]
243 Statement::ShowTriggers(s) => s.fmt(f),
244 Statement::ShowCreateDatabase(s) => s.fmt(f),
245 Statement::ShowCreateView(s) => s.fmt(f),
246 Statement::ShowViews(s) => s.fmt(f),
247 Statement::ShowStatus(s) => s.fmt(f),
248 Statement::ShowSearchPath(s) => s.fmt(f),
249 Statement::DescribeTable(s) => s.fmt(f),
250 Statement::Explain(s) => s.fmt(f),
251 Statement::Copy(s) => s.fmt(f),
252 Statement::Tql(s) => s.fmt(f),
253 Statement::TruncateTable(s) => s.fmt(f),
254 Statement::SetVariables(s) => s.fmt(f),
255 Statement::ShowVariables(s) => s.fmt(f),
256 Statement::ShowCharset(kind) => {
257 write!(f, "SHOW CHARSET {kind}")
258 }
259 Statement::ShowCollation(kind) => {
260 write!(f, "SHOW COLLATION {kind}")
261 }
262 Statement::CreateView(s) => s.fmt(f),
263 Statement::Use(s) => s.fmt(f),
264 Statement::Admin(admin) => admin.fmt(f),
265 Statement::DeclareCursor(s) => s.fmt(f),
266 Statement::FetchCursor(s) => s.fmt(f),
267 Statement::CloseCursor(s) => s.fmt(f),
268 Statement::Kill(k) => k.fmt(f),
269 Statement::ShowProcesslist(s) => s.fmt(f),
270 }
271 }
272}
273
274#[derive(Debug, Clone, PartialEq, Eq)]
278pub struct Hint {
279 pub error_code: Option<u16>,
280 pub comment: String,
281 pub prefix: String,
282}
283
284impl TryFrom<&Statement> for DfStatement {
285 type Error = Error;
286
287 fn try_from(s: &Statement) -> Result<Self, Self::Error> {
288 let s = match s {
289 Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
290 Statement::Explain(explain) => explain.inner.clone(),
291 Statement::Insert(insert) => insert.inner.clone(),
292 Statement::Delete(delete) => delete.inner.clone(),
293 _ => {
294 return ConvertToDfStatementSnafu {
295 statement: format!("{s:?}"),
296 }
297 .fail();
298 }
299 };
300 Ok(DfStatement::Statement(Box::new(s.into())))
301 }
302}