Skip to content

Commit bd2835a

Browse files
committed
Parse ALGORITHM and LOCK options for CREATE INDEX statements
1 parent 400c3cc commit bd2835a

File tree

6 files changed

+58
-1
lines changed

6 files changed

+58
-1
lines changed

src/ast/ddl.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,6 +2344,11 @@ pub struct CreateIndex {
23442344
pub with: Vec<Expr>,
23452345
pub predicate: Option<Expr>,
23462346
pub index_options: Vec<IndexOption>,
2347+
/// [MySQL] allows a subset of options normally used for `ALTER TABLE`:
2348+
///
2349+
/// - `ALGORITHM`
2350+
/// - `LOCK`
2351+
pub alter_options: Vec<AlterTableOperation>,
23472352
}
23482353

23492354
impl fmt::Display for CreateIndex {
@@ -2390,6 +2395,9 @@ impl fmt::Display for CreateIndex {
23902395
if !self.index_options.is_empty() {
23912396
write!(f, " {}", display_separated(&self.index_options, " "))?;
23922397
}
2398+
if !self.alter_options.is_empty() {
2399+
write!(f, " {}", display_separated(&self.alter_options, " "))?;
2400+
}
23932401
Ok(())
23942402
}
23952403
}

src/ast/spans.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ impl Spanned for CreateIndex {
749749
with,
750750
predicate,
751751
index_options: _,
752+
alter_options,
752753
} = self;
753754

754755
union_spans(
@@ -758,7 +759,8 @@ impl Spanned for CreateIndex {
758759
.chain(columns.iter().map(|i| i.column.span()))
759760
.chain(include.iter().map(|i| i.span))
760761
.chain(with.iter().map(|i| i.span()))
761-
.chain(predicate.iter().map(|i| i.span())),
762+
.chain(predicate.iter().map(|i| i.span()))
763+
.chain(alter_options.iter().map(|i| i.span())),
762764
)
763765
}
764766
}

src/parser/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7084,6 +7084,15 @@ impl<'a> Parser<'a> {
70847084
// parse it anyway (as we do inside `ALTER TABLE` and `CREATE TABLE` parsing).
70857085
let index_options = self.parse_index_options()?;
70867086

7087+
// MySQL allows `ALGORITHM` and `LOCK` options. Unlike in `ALTER TABLE`, they need not be comma separated.
7088+
let mut alter_options = Vec::new();
7089+
while self
7090+
.peek_one_of_keywords(&[Keyword::ALGORITHM, Keyword::LOCK])
7091+
.is_some()
7092+
{
7093+
alter_options.push(self.parse_alter_table_operation()?)
7094+
}
7095+
70877096
Ok(Statement::CreateIndex(CreateIndex {
70887097
name: index_name,
70897098
table_name,
@@ -7097,6 +7106,7 @@ impl<'a> Parser<'a> {
70977106
with,
70987107
predicate,
70997108
index_options,
7109+
alter_options,
71007110
}))
71017111
}
71027112

tests/sqlparser_common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9260,6 +9260,7 @@ fn test_create_index_with_using_function() {
92609260
with,
92619261
predicate: None,
92629262
index_options,
9263+
alter_options,
92639264
}) => {
92649265
assert_eq!("idx_name", name.to_string());
92659266
assert_eq!("test", table_name.to_string());
@@ -9271,6 +9272,7 @@ fn test_create_index_with_using_function() {
92719272
assert!(include.is_empty());
92729273
assert!(with.is_empty());
92739274
assert!(index_options.is_empty());
9275+
assert!(alter_options.is_empty());
92749276
}
92759277
_ => unreachable!(),
92769278
}
@@ -9313,6 +9315,7 @@ fn test_create_index_with_with_clause() {
93139315
with,
93149316
predicate: None,
93159317
index_options,
9318+
alter_options,
93169319
}) => {
93179320
pretty_assertions::assert_eq!("title_idx", name.to_string());
93189321
pretty_assertions::assert_eq!("films", table_name.to_string());
@@ -9323,6 +9326,7 @@ fn test_create_index_with_with_clause() {
93239326
assert!(include.is_empty());
93249327
pretty_assertions::assert_eq!(with_parameters, with);
93259328
assert!(index_options.is_empty());
9329+
assert!(alter_options.is_empty());
93269330
}
93279331
_ => unreachable!(),
93289332
}

tests/sqlparser_mysql.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4227,3 +4227,14 @@ fn test_ddl_with_index_using() {
42274227
mysql_and_generic().verified_stmt(&sql);
42284228
}
42294229
}
4230+
4231+
#[test]
4232+
fn test_create_index_options() {
4233+
mysql_and_generic()
4234+
.verified_stmt("CREATE INDEX idx_name ON t(c1, c2) USING HASH LOCK = SHARED");
4235+
mysql_and_generic()
4236+
.verified_stmt("CREATE INDEX idx_name ON t(c1, c2) USING BTREE ALGORITHM = INPLACE");
4237+
mysql_and_generic().verified_stmt(
4238+
"CREATE INDEX idx_name ON t(c1, c2) USING BTREE LOCK = EXCLUSIVE ALGORITHM = DEFAULT",
4239+
);
4240+
}

tests/sqlparser_postgres.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,7 @@ fn parse_create_index() {
25012501
with,
25022502
predicate: None,
25032503
index_options,
2504+
alter_options,
25042505
}) => {
25052506
assert_eq_vec(&["my_index"], &name);
25062507
assert_eq_vec(&["my_table"], &table_name);
@@ -2512,6 +2513,7 @@ fn parse_create_index() {
25122513
assert!(include.is_empty());
25132514
assert!(with.is_empty());
25142515
assert!(index_options.is_empty());
2516+
assert!(alter_options.is_empty());
25152517
}
25162518
_ => unreachable!(),
25172519
}
@@ -2534,6 +2536,7 @@ fn parse_create_anonymous_index() {
25342536
with,
25352537
predicate: None,
25362538
index_options,
2539+
alter_options,
25372540
}) => {
25382541
assert_eq!(None, name);
25392542
assert_eq_vec(&["my_table"], &table_name);
@@ -2545,6 +2548,7 @@ fn parse_create_anonymous_index() {
25452548
assert!(include.is_empty());
25462549
assert!(with.is_empty());
25472550
assert!(index_options.is_empty());
2551+
assert!(alter_options.is_empty());
25482552
}
25492553
_ => unreachable!(),
25502554
}
@@ -2644,6 +2648,7 @@ fn parse_create_indices_with_operator_classes() {
26442648
with,
26452649
predicate: None,
26462650
index_options,
2651+
alter_options,
26472652
}) => {
26482653
assert_eq_vec(&["the_index_name"], &name);
26492654
assert_eq_vec(&["users"], &table_name);
@@ -2652,6 +2657,7 @@ fn parse_create_indices_with_operator_classes() {
26522657
assert!(include.is_empty());
26532658
assert!(with.is_empty());
26542659
assert!(index_options.is_empty());
2660+
assert!(alter_options.is_empty());
26552661
}
26562662
_ => unreachable!(),
26572663
}
@@ -2670,6 +2676,7 @@ fn parse_create_indices_with_operator_classes() {
26702676
with,
26712677
predicate: None,
26722678
index_options,
2679+
alter_options,
26732680
}) => {
26742681
assert_eq_vec(&["the_index_name"], &name);
26752682
assert_eq_vec(&["users"], &table_name);
@@ -2696,6 +2703,7 @@ fn parse_create_indices_with_operator_classes() {
26962703
assert!(include.is_empty());
26972704
assert!(with.is_empty());
26982705
assert!(index_options.is_empty());
2706+
assert!(alter_options.is_empty());
26992707
}
27002708
_ => unreachable!(),
27012709
}
@@ -2721,6 +2729,7 @@ fn parse_create_bloom() {
27212729
with,
27222730
predicate: None,
27232731
index_options,
2732+
alter_options,
27242733
}) => {
27252734
assert_eq_vec(&["bloomidx"], &name);
27262735
assert_eq_vec(&["tbloom"], &table_name);
@@ -2753,6 +2762,7 @@ fn parse_create_bloom() {
27532762
with
27542763
);
27552764
assert!(index_options.is_empty());
2765+
assert!(alter_options.is_empty());
27562766
}
27572767
_ => unreachable!(),
27582768
}
@@ -2775,6 +2785,7 @@ fn parse_create_brin() {
27752785
with,
27762786
predicate: None,
27772787
index_options,
2788+
alter_options,
27782789
}) => {
27792790
assert_eq_vec(&["brin_sensor_data_recorded_at"], &name);
27802791
assert_eq_vec(&["sensor_data"], &table_name);
@@ -2783,6 +2794,7 @@ fn parse_create_brin() {
27832794
assert!(include.is_empty());
27842795
assert!(with.is_empty());
27852796
assert!(index_options.is_empty());
2797+
assert!(alter_options.is_empty());
27862798
}
27872799
_ => unreachable!(),
27882800
}
@@ -2840,6 +2852,7 @@ fn parse_create_index_concurrently() {
28402852
with,
28412853
predicate: None,
28422854
index_options,
2855+
alter_options,
28432856
}) => {
28442857
assert_eq_vec(&["my_index"], &name);
28452858
assert_eq_vec(&["my_table"], &table_name);
@@ -2851,6 +2864,7 @@ fn parse_create_index_concurrently() {
28512864
assert!(include.is_empty());
28522865
assert!(with.is_empty());
28532866
assert!(index_options.is_empty());
2867+
assert!(alter_options.is_empty());
28542868
}
28552869
_ => unreachable!(),
28562870
}
@@ -2873,6 +2887,7 @@ fn parse_create_index_with_predicate() {
28732887
with,
28742888
predicate: Some(_),
28752889
index_options,
2890+
alter_options,
28762891
}) => {
28772892
assert_eq_vec(&["my_index"], &name);
28782893
assert_eq_vec(&["my_table"], &table_name);
@@ -2884,6 +2899,7 @@ fn parse_create_index_with_predicate() {
28842899
assert!(include.is_empty());
28852900
assert!(with.is_empty());
28862901
assert!(index_options.is_empty());
2902+
assert!(alter_options.is_empty());
28872903
}
28882904
_ => unreachable!(),
28892905
}
@@ -2906,6 +2922,7 @@ fn parse_create_index_with_include() {
29062922
with,
29072923
predicate: None,
29082924
index_options,
2925+
alter_options,
29092926
}) => {
29102927
assert_eq_vec(&["my_index"], &name);
29112928
assert_eq_vec(&["my_table"], &table_name);
@@ -2917,6 +2934,7 @@ fn parse_create_index_with_include() {
29172934
assert_eq_vec(&["col3", "col4"], &include);
29182935
assert!(with.is_empty());
29192936
assert!(index_options.is_empty());
2937+
assert!(alter_options.is_empty());
29202938
}
29212939
_ => unreachable!(),
29222940
}
@@ -2939,6 +2957,7 @@ fn parse_create_index_with_nulls_distinct() {
29392957
with,
29402958
predicate: None,
29412959
index_options,
2960+
alter_options,
29422961
}) => {
29432962
assert_eq_vec(&["my_index"], &name);
29442963
assert_eq_vec(&["my_table"], &table_name);
@@ -2951,6 +2970,7 @@ fn parse_create_index_with_nulls_distinct() {
29512970
assert!(!nulls_distinct);
29522971
assert!(with.is_empty());
29532972
assert!(index_options.is_empty());
2973+
assert!(alter_options.is_empty());
29542974
}
29552975
_ => unreachable!(),
29562976
}
@@ -2970,6 +2990,7 @@ fn parse_create_index_with_nulls_distinct() {
29702990
with,
29712991
predicate: None,
29722992
index_options,
2993+
alter_options,
29732994
}) => {
29742995
assert_eq_vec(&["my_index"], &name);
29752996
assert_eq_vec(&["my_table"], &table_name);
@@ -2982,6 +3003,7 @@ fn parse_create_index_with_nulls_distinct() {
29823003
assert!(nulls_distinct);
29833004
assert!(with.is_empty());
29843005
assert!(index_options.is_empty());
3006+
assert!(alter_options.is_empty());
29853007
}
29863008
_ => unreachable!(),
29873009
}

0 commit comments

Comments
 (0)