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 @@ -7094,19 +7094,24 @@ impl<'a> Parser<'a> {
70947094 pub fn parse_create_index(&mut self, unique: bool) -> Result<Statement, ParserError> {
70957095 let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
70967096 let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
7097+
7098+ let mut using = None;
7099+
70977100 let index_name = if if_not_exists || !self.parse_keyword(Keyword::ON) {
70987101 let index_name = self.parse_object_name(false)?;
7102+ // MySQL allows `USING index_type` either before or after `ON table_name`
7103+ using = self.parse_optional_using_then_index_type()?;
70997104 self.expect_keyword_is(Keyword::ON)?;
71007105 Some(index_name)
71017106 } else {
71027107 None
71037108 };
7109+
71047110 let table_name = self.parse_object_name(false)?;
7105- let using = if self.parse_keyword(Keyword::USING) {
7106- Some(self.parse_index_type()?)
7107- } else {
7108- None
7109- };
7111+
7112+ // MySQL allows having two `USING` clauses.
7113+ // In that case, the second clause overwrites the first.
7114+ using = self.parse_optional_using_then_index_type()?.or(using);
71107115
71117116 let columns = self.parse_parenthesized_index_column_list()?;
71127117
Original file line number Diff line number Diff line change @@ -17278,6 +17278,49 @@ fn parse_invisible_column() {
1727817278 }
1727917279}
1728017280
17281+ #[test]
17282+ fn parse_create_index_different_using_positions() {
17283+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1)";
17284+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1)";
17285+ match all_dialects().one_statement_parses_to(sql, expected) {
17286+ Statement::CreateIndex(CreateIndex {
17287+ name,
17288+ table_name,
17289+ using,
17290+ columns,
17291+ unique,
17292+ ..
17293+ }) => {
17294+ assert_eq!(name.unwrap().to_string(), "idx_name");
17295+ assert_eq!(table_name.to_string(), "table_name");
17296+ assert_eq!(using, Some(IndexType::BTree));
17297+ assert_eq!(columns.len(), 1);
17298+ assert!(!unique);
17299+ }
17300+ _ => unreachable!(),
17301+ }
17302+
17303+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1) USING HASH";
17304+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1) USING HASH";
17305+ match all_dialects().one_statement_parses_to(sql, expected) {
17306+ Statement::CreateIndex(CreateIndex {
17307+ name,
17308+ table_name,
17309+ columns,
17310+ index_options,
17311+ ..
17312+ }) => {
17313+ assert_eq!(name.unwrap().to_string(), "idx_name");
17314+ assert_eq!(table_name.to_string(), "table_name");
17315+ assert_eq!(columns.len(), 1);
17316+ assert!(index_options
17317+ .iter()
17318+ .any(|o| o == &IndexOption::Using(IndexType::Hash)));
17319+ }
17320+ _ => unreachable!(),
17321+ }
17322+ }
17323+
1728117324#[test]
1728217325fn test_parse_alter_user() {
1728317326 verified_stmt("ALTER USER u1");
You can’t perform that action at this time.
0 commit comments