Skip to content

Commit 4a0f0b3

Browse files
committed
Support MySQL index options in CREATE TABLE and ALTER TABLE
1 parent 1f9dbf5 commit 4a0f0b3

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

src/ast/ddl.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,8 @@ pub enum TableConstraint {
11251125
index_type: Option<IndexType>,
11261126
/// Referred column identifier list.
11271127
columns: Vec<IndexColumn>,
1128+
/// Optional index options such as `USING`; see [`IndexOption`].
1129+
index_options: Vec<IndexOption>,
11281130
},
11291131
/// MySQLs [fulltext][1] definition. Since the [`SPATIAL`][2] definition is exactly the same,
11301132
/// and MySQL displays both the same way, it is part of this definition as well.
@@ -1253,6 +1255,7 @@ impl fmt::Display for TableConstraint {
12531255
name,
12541256
index_type,
12551257
columns,
1258+
index_options,
12561259
} => {
12571260
write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
12581261
if let Some(name) = name {
@@ -1262,7 +1265,9 @@ impl fmt::Display for TableConstraint {
12621265
write!(f, " USING {index_type}")?;
12631266
}
12641267
write!(f, " ({})", display_comma_separated(columns))?;
1265-
1268+
if !index_options.is_empty() {
1269+
write!(f, " {}", display_comma_separated(index_options))?;
1270+
}
12661271
Ok(())
12671272
}
12681273
Self::FulltextOrSpatial {
@@ -1377,17 +1382,20 @@ impl fmt::Display for IndexType {
13771382
}
13781383
}
13791384

1380-
/// MySQLs index option.
1381-
///
1382-
/// This structure used here [`MySQL` CREATE TABLE][1], [`MySQL` CREATE INDEX][2].
1385+
/// MySQL index option, used in [`CREATE TABLE`], [`CREATE INDEX`], and [`ALTER TABLE`].
13831386
///
1384-
/// [1]: https://dev.mysql.com/doc/refman/8.3/en/create-table.html
1385-
/// [2]: https://dev.mysql.com/doc/refman/8.3/en/create-index.html
1387+
/// [`CREATE TABLE`]: https://dev.mysql.com/doc/refman/8.4/en/create-table.html
1388+
/// [`CREATE INDEX`]: https://dev.mysql.com/doc/refman/8.4/en/create-index.html
1389+
/// [`ALTER TABLE`]: https://dev.mysql.com/doc/refman/8.4/en/alter-table.html
13861390
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
13871391
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13881392
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
13891393
pub enum IndexOption {
1394+
/// `USING { BTREE | HASH }`: Index type to use for the index.
1395+
///
1396+
/// Note that we permissively parse non-MySQL index types, like `GIN`.
13901397
Using(IndexType),
1398+
/// `COMMENT 'string'`: Specifies a comment for the index.
13911399
Comment(String),
13921400
}
13931401

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ impl Spanned for TableConstraint {
713713
name,
714714
index_type: _,
715715
columns,
716+
index_options: _,
716717
} => union_spans(
717718
name.iter()
718719
.map(|i| i.span)

src/parser/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8409,12 +8409,14 @@ impl<'a> Parser<'a> {
84098409

84108410
let index_type = self.parse_optional_using_then_index_type()?;
84118411
let columns = self.parse_parenthesized_index_column_list()?;
8412+
let index_options = self.parse_index_options()?;
84128413

84138414
Ok(Some(TableConstraint::Index {
84148415
display_as_key,
84158416
name,
84168417
index_type,
84178418
columns,
8419+
index_options,
84188420
}))
84198421
}
84208422
Token::Word(w)
@@ -17477,6 +17479,7 @@ mod tests {
1747717479
name: None,
1747817480
index_type: None,
1747917481
columns: vec![mk_expected_col("c1")],
17482+
index_options: vec![],
1748017483
}
1748117484
);
1748217485

@@ -17488,6 +17491,7 @@ mod tests {
1748817491
name: None,
1748917492
index_type: None,
1749017493
columns: vec![mk_expected_col("c1")],
17494+
index_options: vec![],
1749117495
}
1749217496
);
1749317497

@@ -17499,6 +17503,7 @@ mod tests {
1749917503
name: Some(Ident::with_quote('\'', "index")),
1750017504
index_type: None,
1750117505
columns: vec![mk_expected_col("c1"), mk_expected_col("c2")],
17506+
index_options: vec![],
1750217507
}
1750317508
);
1750417509

@@ -17510,6 +17515,7 @@ mod tests {
1751017515
name: None,
1751117516
index_type: Some(IndexType::BTree),
1751217517
columns: vec![mk_expected_col("c1")],
17518+
index_options: vec![],
1751317519
}
1751417520
);
1751517521

@@ -17521,6 +17527,7 @@ mod tests {
1752117527
name: None,
1752217528
index_type: Some(IndexType::Hash),
1752317529
columns: vec![mk_expected_col("c1")],
17530+
index_options: vec![],
1752417531
}
1752517532
);
1752617533

@@ -17532,6 +17539,7 @@ mod tests {
1753217539
name: Some(Ident::new("idx_name")),
1753317540
index_type: Some(IndexType::BTree),
1753417541
columns: vec![mk_expected_col("c1")],
17542+
index_options: vec![],
1753517543
}
1753617544
);
1753717545

@@ -17543,6 +17551,7 @@ mod tests {
1754317551
name: Some(Ident::new("idx_name")),
1754417552
index_type: Some(IndexType::Hash),
1754517553
columns: vec![mk_expected_col("c1")],
17554+
index_options: vec![],
1754617555
}
1754717556
);
1754817557
}

tests/sqlparser_mysql.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,9 +4221,8 @@ fn test_ddl_with_index_using() {
42214221
format!("CREATE TABLE foo (name VARCHAR(255), age INT, KEY idx_name {using} {columns})"),
42224222
format!("ALTER TABLE foo ADD KEY idx_name {using} {columns}"),
42234223
format!("CREATE INDEX idx_name ON test{columns} {using}"),
4224-
// TODO: Add index options to `TableConstraint::Index`
4225-
// format!("CREATE TABLE foo (name VARCHAR(255), age INT, KEY idx_name{columns} {using})"),
4226-
// format!("ALTER TABLE foo ADD KEY idx_name{columns} {using}"),
4224+
format!("CREATE TABLE foo (name VARCHAR(255), age INT, KEY idx_name {columns} {using})"),
4225+
format!("ALTER TABLE foo ADD KEY idx_name {columns} {using}"),
42274226
] {
42284227
mysql_and_generic().verified_stmt(&sql);
42294228
}

0 commit comments

Comments
 (0)