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::query::Query;
36use crate::statements::set_variables::SetVariables;
37use crate::statements::show::{
38    ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
39    ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowRegion, ShowSearchPath, ShowStatus,
40    ShowTableStatus, ShowTables, ShowVariables, ShowViews,
41};
42use crate::statements::tql::Tql;
43use crate::statements::truncate::TruncateTable;
44
45/// Tokens parsed by `DFParser` are converted into these values.
46#[allow(clippy::large_enum_variant)]
47#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
48pub enum Statement {
49    // Query
50    Query(Box<Query>),
51    // Insert
52    Insert(Box<Insert>),
53    // Delete
54    Delete(Box<Delete>),
55    /// CREATE TABLE
56    CreateTable(CreateTable),
57    // CREATE EXTERNAL TABLE
58    CreateExternalTable(CreateExternalTable),
59    // CREATE TABLE ... LIKE
60    CreateTableLike(CreateTableLike),
61    // CREATE FLOW
62    CreateFlow(CreateFlow),
63    // CREATE VIEW ... AS
64    CreateView(CreateView),
65    // DROP TABLE
66    DropTable(DropTable),
67    // DROP DATABASE
68    DropDatabase(DropDatabase),
69    // DROP FLOW
70    DropFlow(DropFlow),
71    // DROP View
72    DropView(DropView),
73    // CREATE DATABASE
74    CreateDatabase(CreateDatabase),
75    /// ALTER TABLE
76    AlterTable(AlterTable),
77    /// ALTER DATABASE
78    AlterDatabase(AlterDatabase),
79    // Databases.
80    ShowDatabases(ShowDatabases),
81    // SHOW TABLES
82    ShowTables(ShowTables),
83    // SHOW TABLE STATUS
84    ShowTableStatus(ShowTableStatus),
85    // SHOW COLUMNS
86    ShowColumns(ShowColumns),
87    // SHOW CHARSET or SHOW CHARACTER SET
88    ShowCharset(ShowKind),
89    // SHOW COLLATION
90    ShowCollation(ShowKind),
91    // SHOW INDEX
92    ShowIndex(ShowIndex),
93    // SHOW REGION
94    ShowRegion(ShowRegion),
95    // SHOW CREATE DATABASE
96    ShowCreateDatabase(ShowCreateDatabase),
97    // SHOW CREATE TABLE
98    ShowCreateTable(ShowCreateTable),
99    // SHOW CREATE FLOW
100    ShowCreateFlow(ShowCreateFlow),
101    /// SHOW FLOWS
102    ShowFlows(ShowFlows),
103    // SHOW CREATE VIEW
104    ShowCreateView(ShowCreateView),
105    // SHOW STATUS
106    ShowStatus(ShowStatus),
107    // SHOW SEARCH_PATH
108    ShowSearchPath(ShowSearchPath),
109    // SHOW VIEWS
110    ShowViews(ShowViews),
111    // DESCRIBE TABLE
112    DescribeTable(DescribeTable),
113    // EXPLAIN QUERY
114    Explain(Explain),
115    // COPY
116    Copy(Copy),
117    // Telemetry Query Language
118    Tql(Tql),
119    // TRUNCATE TABLE
120    TruncateTable(TruncateTable),
121    // SET VARIABLES
122    SetVariables(SetVariables),
123    // SHOW VARIABLES
124    ShowVariables(ShowVariables),
125    // USE
126    Use(String),
127    // Admin statement(extension)
128    Admin(Admin),
129    // DECLARE ... CURSOR FOR ...
130    DeclareCursor(DeclareCursor),
131    // FETCH ... FROM ...
132    FetchCursor(FetchCursor),
133    // CLOSE
134    CloseCursor(CloseCursor),
135}
136
137impl Display for Statement {
138    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139        match self {
140            Statement::Query(s) => s.inner.fmt(f),
141            Statement::Insert(s) => s.inner.fmt(f),
142            Statement::Delete(s) => s.inner.fmt(f),
143            Statement::CreateTable(s) => s.fmt(f),
144            Statement::CreateExternalTable(s) => s.fmt(f),
145            Statement::CreateTableLike(s) => s.fmt(f),
146            Statement::CreateFlow(s) => s.fmt(f),
147            Statement::DropFlow(s) => s.fmt(f),
148            Statement::DropTable(s) => s.fmt(f),
149            Statement::DropDatabase(s) => s.fmt(f),
150            Statement::DropView(s) => s.fmt(f),
151            Statement::CreateDatabase(s) => s.fmt(f),
152            Statement::AlterTable(s) => s.fmt(f),
153            Statement::AlterDatabase(s) => s.fmt(f),
154            Statement::ShowDatabases(s) => s.fmt(f),
155            Statement::ShowTables(s) => s.fmt(f),
156            Statement::ShowTableStatus(s) => s.fmt(f),
157            Statement::ShowColumns(s) => s.fmt(f),
158            Statement::ShowIndex(s) => s.fmt(f),
159            Statement::ShowRegion(s) => s.fmt(f),
160            Statement::ShowCreateTable(s) => s.fmt(f),
161            Statement::ShowCreateFlow(s) => s.fmt(f),
162            Statement::ShowFlows(s) => s.fmt(f),
163            Statement::ShowCreateDatabase(s) => s.fmt(f),
164            Statement::ShowCreateView(s) => s.fmt(f),
165            Statement::ShowViews(s) => s.fmt(f),
166            Statement::ShowStatus(s) => s.fmt(f),
167            Statement::ShowSearchPath(s) => s.fmt(f),
168            Statement::DescribeTable(s) => s.fmt(f),
169            Statement::Explain(s) => s.fmt(f),
170            Statement::Copy(s) => s.fmt(f),
171            Statement::Tql(s) => s.fmt(f),
172            Statement::TruncateTable(s) => s.fmt(f),
173            Statement::SetVariables(s) => s.fmt(f),
174            Statement::ShowVariables(s) => s.fmt(f),
175            Statement::ShowCharset(kind) => {
176                write!(f, "SHOW CHARSET {kind}")
177            }
178            Statement::ShowCollation(kind) => {
179                write!(f, "SHOW COLLATION {kind}")
180            }
181            Statement::CreateView(s) => s.fmt(f),
182            Statement::Use(s) => s.fmt(f),
183            Statement::Admin(admin) => admin.fmt(f),
184            Statement::DeclareCursor(s) => s.fmt(f),
185            Statement::FetchCursor(s) => s.fmt(f),
186            Statement::CloseCursor(s) => s.fmt(f),
187        }
188    }
189}
190
191/// Comment hints from SQL.
192/// It'll be enabled when using `--comment` in mysql client.
193/// Eg: `SELECT * FROM system.number LIMIT 1; -- { ErrorCode 25 }`
194#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct Hint {
196    pub error_code: Option<u16>,
197    pub comment: String,
198    pub prefix: String,
199}
200
201impl TryFrom<&Statement> for DfStatement {
202    type Error = Error;
203
204    fn try_from(s: &Statement) -> Result<Self, Self::Error> {
205        let s = match s {
206            Statement::Query(query) => SpStatement::Query(Box::new(query.inner.clone())),
207            Statement::Explain(explain) => explain.inner.clone(),
208            Statement::Insert(insert) => insert.inner.clone(),
209            Statement::Delete(delete) => delete.inner.clone(),
210            _ => {
211                return ConvertToDfStatementSnafu {
212                    statement: format!("{s:?}"),
213                }
214                .fail();
215            }
216        };
217        Ok(DfStatement::Statement(Box::new(s.into())))
218    }
219}