From 38154c1dfe53362ba929a8a6ebe806e09dcdafa5 Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Sun, 25 Oct 2026 20:28:52 +0100 Subject: [PATCH] MySQL: Share column primary-key parsing --- src/parser/mod.rs | 20 +++--------------- tests/sqlparser_common.rs | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5ecd6e437a..0b31e49907 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -10118,20 +10118,6 @@ impl<'a> Parser<'a> { } else { Ok(Some(ColumnOption::Ephemeral(Some(self.parse_expr()?)))) } - } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) { - let characteristics = self.parse_constraint_characteristics()?; - Ok(Some( - PrimaryKeyConstraint { - name: None, - index_name: None, - index_type: None, - columns: vec![], - include: vec![], - index_options: vec![], - characteristics, - } - .into(), - )) } else if self.parse_keyword(Keyword::UNIQUE) { let index_type_display = if self.dialect.supports_key_column_option() && self.parse_keyword(Keyword::KEY) { @@ -10154,9 +10140,9 @@ impl<'a> Parser<'a> { } .into(), )) - } else if self.dialect.supports_key_column_option() && self.parse_keyword(Keyword::KEY) { - // In MySQL, `KEY` in a column definition is shorthand for `PRIMARY KEY`. - // See: https://dev.mysql.com/doc/refman/8.4/en/create-table.html + } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) + || (self.dialect.supports_key_column_option() && self.parse_keyword(Keyword::KEY)) + { let characteristics = self.parse_constraint_characteristics()?; Ok(Some( PrimaryKeyConstraint { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index dbf09bb763..4dfd4f48f9 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -22230,3 +22230,46 @@ fn parse_div_with_nested_divisor() { } ); } + +#[test] +fn column_key_shorthand_preserves_characteristics_and_unique() { + let dialects = all_dialects_where(|d| d.supports_key_column_option()); + let Statement::CreateTable(table) = dialects.one_statement_parses_to( + "CREATE TABLE t (id INT KEY DEFERRABLE INITIALLY DEFERRED UNIQUE KEY)", + "CREATE TABLE t (id INT PRIMARY KEY DEFERRABLE INITIALLY DEFERRED UNIQUE KEY)", + ) else { + panic!("Expected CREATE TABLE"); + }; + let [ColumnOptionDef { + option: ColumnOption::PrimaryKey(primary), + .. + }, ColumnOptionDef { + option: ColumnOption::Unique(unique), + .. + }] = table.columns[0].options.as_slice() + else { + panic!("Expected primary and unique column options"); + }; + assert_eq!( + primary.characteristics, + Some(ConstraintCharacteristics { + deferrable: Some(true), + initially: Some(DeferrableInitial::Deferred), + enforced: None, + }) + ); + assert_eq!(unique.index_type_display, KeyOrIndexDisplay::Key); +} + +#[test] +fn unsupported_key_column_option_preserves_keyword() { + for dialect in all_dialects_where(|d| !d.supports_key_column_option()).dialects { + let mut parser = Parser::new(dialect.as_ref()).try_with_sql("KEY").unwrap(); + assert_eq!( + parser.parse_optional_column_option(), + Ok(None), + "{dialect:?}" + ); + assert!(parser.parse_keyword(Keyword::KEY), "{dialect:?}"); + } +}