mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-28 19:00:39 +00:00
feat: support explain syntax (#546)
This commit is contained in:
@@ -22,6 +22,7 @@ use crate::error::{
|
||||
self, InvalidDatabaseNameSnafu, InvalidTableNameSnafu, Result, SyntaxSnafu, TokenizerSnafu,
|
||||
};
|
||||
use crate::statements::describe::DescribeTable;
|
||||
use crate::statements::explain::Explain;
|
||||
use crate::statements::show::{ShowCreateTable, ShowDatabases, ShowKind, ShowTables};
|
||||
use crate::statements::statement::Statement;
|
||||
use crate::statements::table_idents_to_full_name;
|
||||
@@ -258,7 +259,16 @@ impl<'a> ParserContext<'a> {
|
||||
}
|
||||
|
||||
fn parse_explain(&mut self) -> Result<Statement> {
|
||||
todo!()
|
||||
let explain_statement =
|
||||
self.parser
|
||||
.parse_explain(false)
|
||||
.with_context(|_| error::UnexpectedSnafu {
|
||||
sql: self.sql,
|
||||
expected: "a query statement",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
|
||||
Ok(Statement::Explain(Explain::try_from(explain_statement)?))
|
||||
}
|
||||
|
||||
// Report unexpected token
|
||||
@@ -328,6 +338,7 @@ impl<'a> ParserContext<'a> {
|
||||
mod tests {
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
use sqlparser::ast::{Query as SpQuery, Statement as SpStatement};
|
||||
use sqlparser::dialect::GenericDialect;
|
||||
|
||||
use super::*;
|
||||
@@ -471,4 +482,54 @@ mod tests {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_explain() {
|
||||
let sql = "EXPLAIN select * from foo";
|
||||
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
|
||||
let stmts = result.unwrap();
|
||||
assert_eq!(1, stmts.len());
|
||||
|
||||
let select = sqlparser::ast::Select {
|
||||
distinct: false,
|
||||
top: None,
|
||||
projection: vec![sqlparser::ast::SelectItem::Wildcard],
|
||||
from: vec![sqlparser::ast::TableWithJoins {
|
||||
relation: sqlparser::ast::TableFactor::Table {
|
||||
name: sqlparser::ast::ObjectName(vec![sqlparser::ast::Ident::new("foo")]),
|
||||
alias: None,
|
||||
args: vec![],
|
||||
with_hints: vec![],
|
||||
},
|
||||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
selection: None,
|
||||
group_by: vec![],
|
||||
cluster_by: vec![],
|
||||
distribute_by: vec![],
|
||||
sort_by: vec![],
|
||||
having: None,
|
||||
};
|
||||
|
||||
let sp_statement = SpStatement::Query(Box::new(SpQuery {
|
||||
with: None,
|
||||
body: sqlparser::ast::SetExpr::Select(Box::new(select)),
|
||||
order_by: vec![],
|
||||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
}));
|
||||
|
||||
let explain = Explain::try_from(SpStatement::Explain {
|
||||
describe_alias: false,
|
||||
analyze: false,
|
||||
verbose: false,
|
||||
statement: Box::new(sp_statement),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(stmts[0], Statement::Explain(explain))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
pub mod alter;
|
||||
pub mod create;
|
||||
pub mod describe;
|
||||
pub mod explain;
|
||||
pub mod insert;
|
||||
pub mod query;
|
||||
pub mod show;
|
||||
|
||||
37
src/sql/src/statements/explain.rs
Normal file
37
src/sql/src/statements/explain.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Greptime Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use sqlparser::ast::Statement as SpStatement;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
/// Explain statement.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Explain {
|
||||
pub inner: SpStatement,
|
||||
}
|
||||
|
||||
impl TryFrom<SpStatement> for Explain {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: SpStatement) -> Result<Self, Self::Error> {
|
||||
Ok(Explain { inner: value })
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Explain {
|
||||
fn to_string(&self) -> String {
|
||||
self.inner.to_string()
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,13 @@ use sqlparser::parser::ParserError;
|
||||
use crate::statements::alter::AlterTable;
|
||||
use crate::statements::create::{CreateDatabase, CreateTable};
|
||||
use crate::statements::describe::DescribeTable;
|
||||
use crate::statements::explain::Explain;
|
||||
use crate::statements::insert::Insert;
|
||||
use crate::statements::query::Query;
|
||||
use crate::statements::show::{ShowCreateTable, ShowDatabases, ShowTables};
|
||||
|
||||
/// Tokens parsed by `DFParser` are converted into these values.
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Statement {
|
||||
// Query
|
||||
@@ -43,6 +45,8 @@ pub enum Statement {
|
||||
ShowCreateTable(ShowCreateTable),
|
||||
// DESCRIBE TABLE
|
||||
DescribeTable(DescribeTable),
|
||||
// EXPLAIN QUERY
|
||||
Explain(Explain),
|
||||
}
|
||||
|
||||
/// Converts Statement to sqlparser statement
|
||||
@@ -68,6 +72,7 @@ impl TryFrom<Statement> for SpStatement {
|
||||
Statement::CreateDatabase(_) | Statement::CreateTable(_) | Statement::Alter(_) => {
|
||||
unimplemented!()
|
||||
}
|
||||
Statement::Explain(e) => Ok(e.inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user