From 5f2886bd5981d02942ee0a0b412abd125554e4b4 Mon Sep 17 00:00:00 2001 From: artorias1024 <82564604+artorias1024@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:58:31 +0800 Subject: [PATCH] feat: Add support for parsing the syntax of MySQL UNIQUE KEY. (#962) Co-authored-by: yukunpeng Co-authored-by: Andrew Lamb --- src/parser/mod.rs | 12 ++++++--- tests/sqlparser_mysql.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2d28b9dd1..75ecb2ddb 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3977,9 +3977,15 @@ impl<'a> Parser<'a> { match next_token.token { Token::Word(w) if w.keyword == Keyword::PRIMARY || w.keyword == Keyword::UNIQUE => { let is_primary = w.keyword == Keyword::PRIMARY; - if is_primary { - self.expect_keyword(Keyword::KEY)?; - } + + // parse optional [KEY] + let _ = self.parse_keyword(Keyword::KEY); + + // optional constraint name + let name = self + .maybe_parse(|parser| parser.parse_identifier()) + .or(name); + let columns = self.parse_parenthesized_column_list(Mandatory, false)?; Ok(Some(TableConstraint::Unique { name, diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 1bb09b4b0..d081e3ac9 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -297,6 +297,62 @@ fn parse_create_table_auto_increment() { } } +#[test] +fn parse_create_table_unique_key() { + let sql = "CREATE TABLE foo (id INT PRIMARY KEY AUTO_INCREMENT, bar INT NOT NULL, UNIQUE KEY bar_key (bar))"; + let canonical = "CREATE TABLE foo (id INT PRIMARY KEY AUTO_INCREMENT, bar INT NOT NULL, CONSTRAINT bar_key UNIQUE (bar))"; + match mysql().one_statement_parses_to(sql, canonical) { + Statement::CreateTable { + name, + columns, + constraints, + .. + } => { + assert_eq!(name.to_string(), "foo"); + assert_eq!( + vec![TableConstraint::Unique { + name: Some(Ident::new("bar_key")), + columns: vec![Ident::new("bar")], + is_primary: false + }], + constraints + ); + assert_eq!( + vec![ + ColumnDef { + name: Ident::new("id"), + data_type: DataType::Int(None), + collation: None, + options: vec![ + ColumnOptionDef { + name: None, + option: ColumnOption::Unique { is_primary: true }, + }, + ColumnOptionDef { + name: None, + option: ColumnOption::DialectSpecific(vec![Token::make_keyword( + "AUTO_INCREMENT" + )]), + }, + ], + }, + ColumnDef { + name: Ident::new("bar"), + data_type: DataType::Int(None), + collation: None, + options: vec![ColumnOptionDef { + name: None, + option: ColumnOption::NotNull, + },], + }, + ], + columns + ); + } + _ => unreachable!(), + } +} + #[test] fn parse_create_table_comment() { let canonical = "CREATE TABLE foo (bar INT) COMMENT 'baz'";