File tree Expand file tree Collapse file tree 3 files changed +55
-5
lines changed Expand file tree Collapse file tree 3 files changed +55
-5
lines changed Original file line number Diff line number Diff line change @@ -2361,6 +2361,8 @@ pub struct CreateIndex {
23612361 pub name : Option < ObjectName > ,
23622362 #[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
23632363 pub table_name : ObjectName ,
2364+ /// Index type used in the statement. Can also be found inside [`CreateIndex::index_options`]
2365+ /// depending on the position of the option within the statement.
23642366 pub using : Option < IndexType > ,
23652367 pub columns : Vec < IndexColumn > ,
23662368 pub unique : bool ,
Original file line number Diff line number Diff line change @@ -7063,19 +7063,24 @@ impl<'a> Parser<'a> {
70637063 pub fn parse_create_index(&mut self, unique: bool) -> Result<Statement, ParserError> {
70647064 let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
70657065 let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
7066+
7067+ let mut using = None;
7068+
70667069 let index_name = if if_not_exists || !self.parse_keyword(Keyword::ON) {
70677070 let index_name = self.parse_object_name(false)?;
7071+ // MySQL allows `USING index_type` either before or after `ON table_name`
7072+ using = self.parse_optional_using_then_index_type()?;
70687073 self.expect_keyword_is(Keyword::ON)?;
70697074 Some(index_name)
70707075 } else {
70717076 None
70727077 };
7078+
70737079 let table_name = self.parse_object_name(false)?;
7074- let using = if self.parse_keyword(Keyword::USING) {
7075- Some(self.parse_index_type()?)
7076- } else {
7077- None
7078- };
7080+
7081+ // MySQL allows having two `USING` clauses.
7082+ // In that case, the second clause overwrites the first.
7083+ using = self.parse_optional_using_then_index_type()?.or(using);
70797084
70807085 let columns = self.parse_parenthesized_index_column_list()?;
70817086
Original file line number Diff line number Diff line change @@ -17252,6 +17252,49 @@ fn parse_invisible_column() {
1725217252 }
1725317253}
1725417254
17255+ #[test]
17256+ fn parse_create_index_different_using_positions() {
17257+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1)";
17258+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1)";
17259+ match all_dialects().one_statement_parses_to(sql, expected) {
17260+ Statement::CreateIndex(CreateIndex {
17261+ name,
17262+ table_name,
17263+ using,
17264+ columns,
17265+ unique,
17266+ ..
17267+ }) => {
17268+ assert_eq!(name.unwrap().to_string(), "idx_name");
17269+ assert_eq!(table_name.to_string(), "table_name");
17270+ assert_eq!(using, Some(IndexType::BTree));
17271+ assert_eq!(columns.len(), 1);
17272+ assert!(!unique);
17273+ }
17274+ _ => unreachable!(),
17275+ }
17276+
17277+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1) USING HASH";
17278+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1) USING HASH";
17279+ match all_dialects().one_statement_parses_to(sql, expected) {
17280+ Statement::CreateIndex(CreateIndex {
17281+ name,
17282+ table_name,
17283+ columns,
17284+ index_options,
17285+ ..
17286+ }) => {
17287+ assert_eq!(name.unwrap().to_string(), "idx_name");
17288+ assert_eq!(table_name.to_string(), "table_name");
17289+ assert_eq!(columns.len(), 1);
17290+ assert!(index_options
17291+ .iter()
17292+ .any(|o| o == &IndexOption::Using(IndexType::Hash)));
17293+ }
17294+ _ => unreachable!(),
17295+ }
17296+ }
17297+
1725517298#[test]
1725617299fn test_parse_alter_user() {
1725717300 verified_stmt("ALTER USER u1");
You can’t perform that action at this time.
0 commit comments