diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6f81e1e4e..4d642919e 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3941,9 +3941,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 00901799f..5aeffb0b6 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'";