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 {
2361
2361
pub name : Option < ObjectName > ,
2362
2362
#[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
2363
2363
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.
2364
2366
pub using : Option < IndexType > ,
2365
2367
pub columns : Vec < IndexColumn > ,
2366
2368
pub unique : bool ,
Original file line number Diff line number Diff line change @@ -7063,19 +7063,24 @@ impl<'a> Parser<'a> {
7063
7063
pub fn parse_create_index(&mut self, unique: bool) -> Result<Statement, ParserError> {
7064
7064
let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
7065
7065
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
7066
+
7067
+ let mut using = None;
7068
+
7066
7069
let index_name = if if_not_exists || !self.parse_keyword(Keyword::ON) {
7067
7070
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()?;
7068
7073
self.expect_keyword_is(Keyword::ON)?;
7069
7074
Some(index_name)
7070
7075
} else {
7071
7076
None
7072
7077
};
7078
+
7073
7079
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);
7079
7084
7080
7085
let columns = self.parse_parenthesized_index_column_list()?;
7081
7086
Original file line number Diff line number Diff line change @@ -17252,6 +17252,49 @@ fn parse_invisible_column() {
17252
17252
}
17253
17253
}
17254
17254
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
+
17255
17298
#[test]
17256
17299
fn test_parse_alter_user() {
17257
17300
verified_stmt("ALTER USER u1");
You can’t perform that action at this time.
0 commit comments