sql/statements/
statement.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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/// Tokens parsed by `DFParser` are converted into these values.
47#[allow(clippy::large_enum_variant)]
48#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
49pub enum Statement {
50    // Query
51    Query(Box<Query>),
52    // Insert
53    Insert(Box<Insert>),
54    // Delete
55    Delete(Box<Delete>),
56    /// CREATE TABLE
57    CreateTable(CreateTable),
58    // CREATE EXTERNAL TABLE
59    CreateExternalTable(CreateExternalTable),
60    // CREATE TABLE ... LIKE
61    CreateTableLike(CreateTableLike),
62    // CREATE FLOW
63    CreateFlow(CreateFlow),
64    // CREATE VIEW ... AS
65    CreateView(CreateView),
66    // CREATE TRIGGER
67    #[cfg(feature = "enterprise")]
68    CreateTrigger(crate::statements::create::trigger::CreateTrigger),
69    // DROP TABLE
70    DropTable(DropTable),
71    // DROP DATABASE
72    DropDatabase(DropDatabase),
73    // DROP FLOW
74    DropFlow(DropFlow),
75    // DROP Trigger
76    #[cfg(feature = "enterprise")]
77    DropTrigger(crate::statements::drop::trigger::DropTrigger),
78    // DROP View
79    DropView(DropView),
80    // CREATE DATABASE
81    CreateDatabase(CreateDatabase),
82    /// ALTER TABLE
83    AlterTable(AlterTable),
84    /// ALTER DATABASE
85    AlterDatabase(AlterDatabase),
86    // Databases.
87    ShowDatabases(ShowDatabases),
88    // SHOW TABLES
89    ShowTables(ShowTables),
90    // SHOW TABLE STATUS
91    ShowTableStatus(ShowTableStatus),
92    // SHOW COLUMNS
93    ShowColumns(ShowColumns),
94    // SHOW CHARSET or SHOW CHARACTER SET
95    ShowCharset(ShowKind),
96    // SHOW COLLATION
97    ShowCollation(ShowKind),
98    // SHOW INDEX
99    ShowIndex(ShowIndex),
100    // SHOW REGION
101    ShowRegion(ShowRegion),
102    // SHOW CREATE DATABASE
103    ShowCreateDatabase(ShowCreateDatabase),
104    // SHOW CREATE TABLE
105    ShowCreateTable(ShowCreateTable),
106    // SHOW CREATE FLOW
107    ShowCreateFlow(ShowCreateFlow),
108    /// SHOW FLOWS
109    ShowFlows(ShowFlows),
110    // SHOW TRIGGERS
111    #[cfg(feature = "enterprise")]
112    ShowTriggers(crate::statements::show::trigger::ShowTriggers),
113    // SHOW CREATE VIEW
114    ShowCreateView(ShowCreateView),
115    // SHOW STATUS
116    ShowStatus(ShowStatus),
117    // SHOW SEARCH_PATH
118    ShowSearchPath(ShowSearchPath),
119    // SHOW VIEWS
120    ShowViews(ShowViews),
121    // DESCRIBE TABLE
122    DescribeTable(DescribeTable),
123    // EXPLAIN QUERY
124    Explain(Explain),
125    // COPY
126    Copy(Copy),
127    // Telemetry Query Language
128    Tql(Tql),
129    // TRUNCATE TABLE
130    TruncateTable(TruncateTable),
131    // SET VARIABLES
132    SetVariables(SetVariables),
133    // SHOW VARIABLES
134    ShowVariables(ShowVariables),
135    // USE
136    Use(String),
137    // Admin statement(extension)
138    Admin(Admin),
139    // DECLARE ... CURSOR FOR ...
140    DeclareCursor(DeclareCursor),
141    // FETCH ... FROM ...
142    FetchCursor(FetchCursor),
143    // CLOSE
144    CloseCursor(CloseCursor),
145    // KILL <process>
146    Kill(Kill),
147    // SHOW PROCESSLIST
148    ShowProcesslist(ShowProcessList),
149}
150
151impl Display for Statement {
152    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
153        match self {
154            Statement::Query(s) => s.inner.fmt(f),
155            Statement::Insert(s) => s.inner.fmt(f),
156            Statement::Delete(s) => s.inner.fmt(f),
157            Statement::CreateTable(s) => s.fmt(f),
158            Statement::CreateExternalTable(s) => s.fmt(f),
159            Statement::CreateTableLike(s) => s.fmt(f),
160            Statement::CreateFlow(s) => s.fmt(f),
161            #[cfg(feature = "enterprise")]
162            Statement::CreateTrigger(s) => s.fmt(f),
163            Statement::DropFlow(s) => s.fmt(f),
164            #[cfg(feature = "enterprise")]
165            Statement::DropTrigger(s) => s.fmt(f),
166            Statement::DropTable(s) => s.fmt(f),
167            Statement::DropDatabase(s) => s.fmt(f),
168            Statement::DropView(s) => s.fmt(f),
169            Statement::CreateDatabase(s) => s.fmt(f),
170            Statement::AlterTable(s) => s.fmt(f),
171            Statement::AlterDatabase(s) => s.fmt(f),
172            Statement::ShowDatabases(s) => s.fmt(f),
173            Statement::ShowTables(s) => s.fmt(f),
174            Statement::ShowTableStatus(s) => s.fmt(f),
175            Statement::ShowColumns(s) => s.fmt(f),
176            Statement::ShowIndex(s) => s.fmt(f),
177            Statement::ShowRegion(s) => s.fmt(f),
178            Statement::ShowCreateTable(s) => s.fmt(f),
179            Statement::ShowCreateFlow(s) => s.fmt(f),
180            Statement::ShowFlows(s) => s.fmt(f),
181            #[cfg(feature = "enterprise")]
182            Statement::ShowTriggers(s) => s.fmt(f),
183            Statement::ShowCreateDatabase(s) => s.fmt(f),
184            Statement::ShowCreateView(s) => s.fmt(f),
185            Statement::ShowViews(s) => s.fmt(f),
186            Statement::ShowStatus(s) => s.fmt(f),
187            Statement::ShowSearchPath(s) => s.fmt(f),
188            Statement::DescribeTable(s) => s.fmt(f),
189            Statement::Explain(s) => s.fmt(f),
190            Statement::Copy(s) => s.fmt(f),
191            Statement::Tql(s) => s.fmt(f),
192            Statement::TruncateTable(s) => s.fmt(f),
193            Statement::SetVariables(s) => s.fmt(f),
194            Statement::ShowVariables(s) => s.fmt(f),
195            Statement::ShowCharset(kind) => {
196                write!(f, "SHOW CHARSET {kind}")
197            }
198            Statement::ShowCollation(kind) => {
199                write!(f, "SHOW COLLATION {kind}")
200            }
201            Statement::CreateView(s) => s.fmt(f),
202            Statement::Use(s) => s.fmt(f),
203            Statement::Admin(admin) => admin.fmt(f),
204            Statement::DeclareCursor(s) => s.fmt(f),
205            Statement::FetchCursor(s) => s.fmt(f),
206            Statement::CloseCursor(s) => s.fmt(f),
207            Statement::Kill(k) => k.fmt(f),
208            Statement::ShowProcesslist(s) => s.fmt(f),
209        }
210    }
211}
212
213/// Comment hints from SQL.
214/// It'll be enabled when using `--comment` in mysql client.
215/// Eg: `SELECT * FROM system.number LIMIT 1; -- { ErrorCode 25 }`
216#[derive(Debug, Clone, PartialEq, Eq)]
217pub struct Hint {
218    pub error_code: Option<u16>,
219    pub comment: String,
220    pub prefix: String,
221}
222
223impl TryFrom<&Statement> for DfStatement {
224    type Error = Error;
225
226    fn try_from(s: &Statement) -> Result<Self, Self::Error> {
227        let s = match s {
228            Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
229            Statement::Explain(explain) => explain.inner.clone(),
230            Statement::Insert(insert) => insert.inner.clone(),
231            Statement::Delete(delete) => delete.inner.clone(),
232            _ => {
233                return ConvertToDfStatementSnafu {
234                    statement: format!("{s:?}"),
235                }
236                .fail();
237            }
238        };
239        Ok(DfStatement::Statement(Box::new(s.into())))
240    }
241}