feat: Allow sql parser to parse show-create-table statement (#347)

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement

* feat: Add ShowCreateTable to Statement
This commit is contained in:
Sheng hui
2022-11-08 16:35:56 +08:00
committed by GitHub
parent a2f9b788f1
commit cff8fe4e0e
6 changed files with 76 additions and 4 deletions

View File

@@ -77,6 +77,9 @@ impl Instance {
Statement::ShowTables(stmt) => {
self.sql_handler.execute(SqlRequest::ShowTables(stmt)).await
}
Statement::ShowCreateTable(_stmt) => {
unimplemented!("SHOW CREATE TABLE is unimplemented yet");
}
}
}
}

View File

@@ -48,6 +48,7 @@ where
Statement::Query(qb) => self.query_to_plan(qb),
Statement::ShowTables(_)
| Statement::ShowDatabases(_)
| Statement::ShowCreateTable(_)
| Statement::Create(_)
| Statement::Alter(_)
| Statement::Insert(_) => unreachable!(),

View File

@@ -83,6 +83,9 @@ pub enum Error {
#[snafu(display("Invalid database name: {}", name))]
InvalidDatabaseName { name: String, backtrace: Backtrace },
#[snafu(display("Invalid table name: {}", name))]
InvalidTableName { name: String, backtrace: Backtrace },
#[snafu(display("Invalid default constraint, column: {}, source: {}", column, source))]
InvalidDefault {
column: String,
@@ -106,7 +109,9 @@ impl ErrorExt for Error {
| SqlTypeNotSupported { .. }
| InvalidDefault { .. } => StatusCode::InvalidSyntax,
InvalidDatabaseName { .. } | ColumnTypeMismatch { .. } => StatusCode::InvalidArguments,
InvalidDatabaseName { .. } | ColumnTypeMismatch { .. } | InvalidTableName { .. } => {
StatusCode::InvalidArguments
}
}
}

View File

@@ -5,8 +5,10 @@ use sqlparser::parser::Parser;
use sqlparser::parser::ParserError;
use sqlparser::tokenizer::{Token, Tokenizer};
use crate::error::{self, InvalidDatabaseNameSnafu, Result, SyntaxSnafu, TokenizerSnafu};
use crate::statements::show::{ShowDatabases, ShowKind, ShowTables};
use crate::error::{
self, InvalidDatabaseNameSnafu, InvalidTableNameSnafu, Result, SyntaxSnafu, TokenizerSnafu,
};
use crate::statements::show::{ShowCreateTable, ShowDatabases, ShowKind, ShowTables};
use crate::statements::statement::Statement;
/// GrepTime SQL parser context, a simple wrapper for Datafusion SQL parser.
@@ -102,11 +104,38 @@ impl<'a> ParserContext<'a> {
} else if self.matches_keyword(Keyword::TABLES) {
self.parser.next_token();
self.parse_show_tables()
} else if self.consume_token("CREATE") {
if self.consume_token("TABLE") {
self.parse_show_create_table()
} else {
self.unsupported(self.peek_token_as_string())
}
} else {
self.unsupported(self.peek_token_as_string())
}
}
/// Parse SHOW CREATE TABLE statement
fn parse_show_create_table(&mut self) -> Result<Statement> {
let table_name =
self.parser
.parse_object_name()
.with_context(|_| error::UnexpectedSnafu {
sql: self.sql,
expected: "a table name",
actual: self.peek_token_as_string(),
})?;
ensure!(
!table_name.0.is_empty(),
InvalidTableNameSnafu {
name: table_name.to_string(),
}
);
Ok(Statement::ShowCreateTable(ShowCreateTable {
table_name: table_name.to_string(),
}))
}
fn parse_show_tables(&mut self) -> Result<Statement> {
let database = match self.parser.peek_token() {
Token::EOF | Token::SemiColon => {

View File

@@ -40,6 +40,12 @@ pub struct ShowTables {
pub database: Option<String>,
}
/// SQL structure for `SHOW CREATE TABLE`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ShowCreateTable {
pub table_name: String,
}
#[cfg(test)]
mod tests {
use std::assert_matches::assert_matches;
@@ -94,4 +100,27 @@ mod tests {
}
}
}
#[test]
pub fn test_show_create_table() {
let sql = "SHOW CREATE TABLE test";
let stmts: Vec<Statement> =
ParserContext::create_with_dialect(sql, &GenericDialect {}).unwrap();
assert_eq!(1, stmts.len());
assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
match &stmts[0] {
Statement::ShowCreateTable(show) => {
let table_name = show.table_name.as_str();
assert_eq!(table_name, "test");
}
_ => {
unreachable!();
}
}
}
#[test]
pub fn test_show_create_missing_table_name() {
let sql = "SHOW CREATE TABLE";
ParserContext::create_with_dialect(sql, &GenericDialect {}).unwrap_err();
}
}

View File

@@ -5,7 +5,7 @@ use crate::statements::alter::AlterTable;
use crate::statements::create_table::CreateTable;
use crate::statements::insert::Insert;
use crate::statements::query::Query;
use crate::statements::show::{ShowDatabases, ShowTables};
use crate::statements::show::{ShowCreateTable, ShowDatabases, ShowTables};
/// Tokens parsed by `DFParser` are converted into these values.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -22,6 +22,8 @@ pub enum Statement {
ShowDatabases(ShowDatabases),
// SHOW TABLES
ShowTables(ShowTables),
// SHOW CREATE TABLE
ShowCreateTable(ShowCreateTable),
}
/// Converts Statement to sqlparser statement
@@ -36,6 +38,9 @@ impl TryFrom<Statement> for SpStatement {
Statement::ShowTables(_) => Err(ParserError::ParserError(
"sqlparser does not support SHOW TABLES query.".to_string(),
)),
Statement::ShowCreateTable(_) => Err(ParserError::ParserError(
"sqlparser does not support SHOW CREATE TABLE query.".to_string(),
)),
Statement::Query(s) => Ok(SpStatement::Query(Box::new(s.inner))),
Statement::Insert(i) => Ok(i.inner),
Statement::Create(_) | Statement::Alter(_) => unimplemented!(),