feat: support explain syntax (#546)

This commit is contained in:
Francis Du
2022-11-22 21:22:32 +08:00
committed by GitHub
parent 9f865b50ab
commit 4a9cf49637
15 changed files with 192 additions and 11 deletions

View File

@@ -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))
}
}

View File

@@ -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;

View 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()
}
}

View File

@@ -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),
}
}
}