feat: Support SHOW CREATE TABLE|EVENT|FUNCTION (MySQL specific) (#338)

* feat: Support SHOW CREATE TABLE|EVENT|FUNCTION (MySQL specific)

* misc: Simplify test with loop over enum values
This commit is contained in:
Dmitry Patsura 2021-08-29 14:03:39 +03:00 committed by GitHub
parent 69af5a1d99
commit 9a5716d94b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 1 deletions

View file

@ -523,6 +523,28 @@ impl fmt::Display for AddDropSync {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ShowCreateObject {
Event,
Function,
Procedure,
Table,
Trigger,
}
impl fmt::Display for ShowCreateObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ShowCreateObject::Event => f.write_str("EVENT"),
ShowCreateObject::Function => f.write_str("FUNCTION"),
ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
ShowCreateObject::Table => f.write_str("TABLE"),
ShowCreateObject::Trigger => f.write_str("TRIGGER"),
}
}
}
/// A top-level statement (SELECT, INSERT, CREATE, etc.) /// A top-level statement (SELECT, INSERT, CREATE, etc.)
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -685,6 +707,13 @@ pub enum Statement {
/// ///
/// Note: this is a PostgreSQL-specific statement. /// Note: this is a PostgreSQL-specific statement.
ShowVariable { variable: Vec<Ident> }, ShowVariable { variable: Vec<Ident> },
/// SHOW CREATE TABLE
///
/// Note: this is a MySQL-specific statement.
ShowCreate {
obj_type: ShowCreateObject,
obj_name: ObjectName,
},
/// SHOW COLUMNS /// SHOW COLUMNS
/// ///
/// Note: this is a MySQL-specific statement. /// Note: this is a MySQL-specific statement.
@ -1196,6 +1225,15 @@ impl fmt::Display for Statement {
} }
Ok(()) Ok(())
} }
Statement::ShowCreate { obj_type, obj_name } => {
write!(
f,
"SHOW CREATE {obj_type} {obj_name}",
obj_type = obj_type,
obj_name = obj_name,
)?;
Ok(())
}
Statement::ShowColumns { Statement::ShowColumns {
extended, extended,
full, full,

View file

@ -193,6 +193,7 @@ define_keywords!(
EQUALS, EQUALS,
ERROR, ERROR,
ESCAPE, ESCAPE,
EVENT,
EVERY, EVERY,
EXCEPT, EXCEPT,
EXEC, EXEC,

View file

@ -2541,7 +2541,9 @@ impl<'a> Parser<'a> {
.is_some() .is_some()
{ {
self.prev_token(); self.prev_token();
self.parse_show_columns() Ok(self.parse_show_columns()?)
} else if self.parse_one_of_keywords(&[Keyword::CREATE]).is_some() {
Ok(self.parse_show_create()?)
} else { } else {
Ok(Statement::ShowVariable { Ok(Statement::ShowVariable {
variable: self.parse_identifiers()?, variable: self.parse_identifiers()?,
@ -2549,6 +2551,30 @@ impl<'a> Parser<'a> {
} }
} }
fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
let obj_type = match self.expect_one_of_keywords(&[
Keyword::TABLE,
Keyword::TRIGGER,
Keyword::FUNCTION,
Keyword::PROCEDURE,
Keyword::EVENT,
])? {
Keyword::TABLE => Ok(ShowCreateObject::Table),
Keyword::TRIGGER => Ok(ShowCreateObject::Trigger),
Keyword::FUNCTION => Ok(ShowCreateObject::Function),
Keyword::PROCEDURE => Ok(ShowCreateObject::Procedure),
Keyword::EVENT => Ok(ShowCreateObject::Event),
keyword => Err(ParserError::ParserError(format!(
"Unable to map keyword to ShowCreateObject: {:?}",
keyword
))),
}?;
let obj_name = self.parse_object_name()?;
Ok(Statement::ShowCreate { obj_type, obj_name })
}
fn parse_show_columns(&mut self) -> Result<Statement, ParserError> { fn parse_show_columns(&mut self) -> Result<Statement, ParserError> {
let extended = self.parse_keyword(Keyword::EXTENDED); let extended = self.parse_keyword(Keyword::EXTENDED);
let full = self.parse_keyword(Keyword::FULL); let full = self.parse_keyword(Keyword::FULL);

View file

@ -100,6 +100,27 @@ fn parse_show_columns() {
} }
} }
#[test]
fn parse_show_create() {
let obj_name = ObjectName(vec![Ident::new("myident")]);
for obj_type in &vec![
ShowCreateObject::Table,
ShowCreateObject::Trigger,
ShowCreateObject::Event,
ShowCreateObject::Function,
ShowCreateObject::Procedure,
] {
assert_eq!(
mysql_and_generic().verified_stmt(format!("SHOW CREATE {} myident", obj_type).as_str()),
Statement::ShowCreate {
obj_type: obj_type.clone(),
obj_name: obj_name.clone(),
}
);
}
}
#[test] #[test]
fn parse_create_table_auto_increment() { fn parse_create_table_auto_increment() {
let sql = "CREATE TABLE foo (bar INT PRIMARY KEY AUTO_INCREMENT)"; let sql = "CREATE TABLE foo (bar INT PRIMARY KEY AUTO_INCREMENT)";