Skip to content

Commit 3d2a225

Browse files
committed
Add ASYNC keyword support for CREATE INDEX
Amazon Aurora DSQL uses `CREATE INDEX ASYNC` to create indexes asynchronously. This adds parsing support for the ASYNC keyword in CREATE INDEX statements. Changes: - Add ASYNC keyword to the keyword list - Add `async` field to CreateIndex struct - Parse ASYNC keyword after CONCURRENTLY in parse_create_index - Round-trip support via Display impl - Tests for CREATE INDEX ASYNC and CREATE UNIQUE INDEX ASYNC
1 parent 67d684b commit 3d2a225

6 files changed

Lines changed: 82 additions & 1 deletion

File tree

src/ast/ddl.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2818,6 +2818,8 @@ pub struct CreateIndex {
28182818
pub unique: bool,
28192819
/// whether the index is created concurrently
28202820
pub concurrently: bool,
2821+
/// whether the index is created asynchronously
2822+
pub r#async: bool,
28212823
/// IF NOT EXISTS clause
28222824
pub if_not_exists: bool,
28232825
/// INCLUDE clause: <https://www.postgresql.org/docs/current/sql-createindex.html>
@@ -2843,13 +2845,14 @@ impl fmt::Display for CreateIndex {
28432845
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28442846
write!(
28452847
f,
2846-
"CREATE {unique}INDEX {concurrently}{if_not_exists}",
2848+
"CREATE {unique}INDEX {concurrently}{async_}{if_not_exists}",
28472849
unique = if self.unique { "UNIQUE " } else { "" },
28482850
concurrently = if self.concurrently {
28492851
"CONCURRENTLY "
28502852
} else {
28512853
""
28522854
},
2855+
async_ = if self.r#async { "ASYNC " } else { "" },
28532856
if_not_exists = if self.if_not_exists {
28542857
"IF NOT EXISTS "
28552858
} else {

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ impl Spanned for CreateIndex {
682682
columns,
683683
unique: _, // bool
684684
concurrently: _, // bool
685+
r#async: _, // bool
685686
if_not_exists: _, // bool
686687
include,
687688
nulls_distinct: _, // bool

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ define_keywords!(
131131
ASOF,
132132
ASSERT,
133133
ASYMMETRIC,
134+
ASYNC,
134135
AT,
135136
ATOMIC,
136137
ATTACH,

src/parser/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8029,6 +8029,7 @@ impl<'a> Parser<'a> {
80298029
/// Parse a `CREATE INDEX` statement.
80308030
pub fn parse_create_index(&mut self, unique: bool) -> Result<CreateIndex, ParserError> {
80318031
let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
8032+
let r#async = self.parse_keyword(Keyword::ASYNC);
80328033
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
80338034

80348035
let mut using = None;
@@ -8108,6 +8109,7 @@ impl<'a> Parser<'a> {
81088109
columns,
81098110
unique,
81108111
concurrently,
8112+
r#async,
81118113
if_not_exists,
81128114
include,
81138115
nulls_distinct,

tests/sqlparser_common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9541,6 +9541,7 @@ fn test_create_index_with_using_function() {
95419541
columns,
95429542
unique,
95439543
concurrently,
9544+
r#async,
95449545
if_not_exists,
95459546
include,
95469547
nulls_distinct: None,
@@ -9555,6 +9556,7 @@ fn test_create_index_with_using_function() {
95559556
assert_eq!(indexed_columns, columns);
95569557
assert!(unique);
95579558
assert!(!concurrently);
9559+
assert!(!r#async);
95589560
assert!(if_not_exists);
95599561
assert!(include.is_empty());
95609562
assert!(with.is_empty());
@@ -9596,6 +9598,7 @@ fn test_create_index_with_with_clause() {
95969598
columns,
95979599
unique,
95989600
concurrently,
9601+
r#async,
95999602
if_not_exists,
96009603
include,
96019604
nulls_distinct: None,
@@ -9609,6 +9612,7 @@ fn test_create_index_with_with_clause() {
96099612
pretty_assertions::assert_eq!(indexed_columns, columns);
96109613
assert!(unique);
96119614
assert!(!concurrently);
9615+
assert!(!r#async);
96129616
assert!(!if_not_exists);
96139617
assert!(include.is_empty());
96149618
pretty_assertions::assert_eq!(with_parameters, with);

tests/sqlparser_postgres.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,6 +2806,7 @@ fn parse_create_index() {
28062806
columns,
28072807
unique,
28082808
concurrently,
2809+
r#async,
28092810
if_not_exists,
28102811
nulls_distinct: None,
28112812
include,
@@ -2819,6 +2820,7 @@ fn parse_create_index() {
28192820
assert_eq!(None, using);
28202821
assert!(!unique);
28212822
assert!(!concurrently);
2823+
assert!(!r#async);
28222824
assert!(if_not_exists);
28232825
assert_eq_vec(&["col1", "col2"], &columns);
28242826
assert!(include.is_empty());
@@ -2841,6 +2843,7 @@ fn parse_create_anonymous_index() {
28412843
columns,
28422844
unique,
28432845
concurrently,
2846+
r#async,
28442847
if_not_exists,
28452848
include,
28462849
nulls_distinct: None,
@@ -2854,6 +2857,7 @@ fn parse_create_anonymous_index() {
28542857
assert_eq!(None, using);
28552858
assert!(!unique);
28562859
assert!(!concurrently);
2860+
assert!(!r#async);
28572861
assert!(!if_not_exists);
28582862
assert_eq_vec(&["col1", "col2"], &columns);
28592863
assert!(include.is_empty());
@@ -2959,6 +2963,7 @@ fn parse_create_indices_with_operator_classes() {
29592963
columns,
29602964
unique: false,
29612965
concurrently: false,
2966+
r#async: false,
29622967
if_not_exists: false,
29632968
include,
29642969
nulls_distinct: None,
@@ -2987,6 +2992,7 @@ fn parse_create_indices_with_operator_classes() {
29872992
columns,
29882993
unique: false,
29892994
concurrently: false,
2995+
r#async: false,
29902996
if_not_exists: false,
29912997
include,
29922998
nulls_distinct: None,
@@ -3070,6 +3076,7 @@ fn parse_create_bloom() {
30703076
columns,
30713077
unique: false,
30723078
concurrently: false,
3079+
r#async: false,
30733080
if_not_exists: false,
30743081
include,
30753082
nulls_distinct: None,
@@ -3126,6 +3133,7 @@ fn parse_create_brin() {
31263133
columns,
31273134
unique: false,
31283135
concurrently: false,
3136+
r#async: false,
31293137
if_not_exists: false,
31303138
include,
31313139
nulls_distinct: None,
@@ -3193,6 +3201,7 @@ fn parse_create_index_concurrently() {
31933201
columns,
31943202
unique,
31953203
concurrently,
3204+
r#async,
31963205
if_not_exists,
31973206
include,
31983207
nulls_distinct: None,
@@ -3206,6 +3215,7 @@ fn parse_create_index_concurrently() {
32063215
assert_eq!(None, using);
32073216
assert!(!unique);
32083217
assert!(concurrently);
3218+
assert!(!r#async);
32093219
assert!(if_not_exists);
32103220
assert_eq_vec(&["col1", "col2"], &columns);
32113221
assert!(include.is_empty());
@@ -3217,6 +3227,58 @@ fn parse_create_index_concurrently() {
32173227
}
32183228
}
32193229

3230+
#[test]
3231+
fn parse_create_index_async() {
3232+
let sql = "CREATE INDEX ASYNC my_index ON my_table(col1)";
3233+
match pg().verified_stmt(sql) {
3234+
Statement::CreateIndex(CreateIndex {
3235+
name: Some(ObjectName(name)),
3236+
table_name: ObjectName(table_name),
3237+
using,
3238+
columns,
3239+
unique,
3240+
concurrently,
3241+
r#async,
3242+
if_not_exists,
3243+
include,
3244+
nulls_distinct: None,
3245+
with,
3246+
predicate: None,
3247+
index_options,
3248+
alter_options,
3249+
}) => {
3250+
assert_eq_vec(&["my_index"], &name);
3251+
assert_eq_vec(&["my_table"], &table_name);
3252+
assert_eq!(None, using);
3253+
assert!(!unique);
3254+
assert!(!concurrently);
3255+
assert!(r#async);
3256+
assert!(!if_not_exists);
3257+
assert_eq_vec(&["col1"], &columns);
3258+
assert!(include.is_empty());
3259+
assert!(with.is_empty());
3260+
assert!(index_options.is_empty());
3261+
assert!(alter_options.is_empty());
3262+
}
3263+
_ => unreachable!(),
3264+
}
3265+
3266+
let sql = "CREATE UNIQUE INDEX ASYNC my_index ON my_table(col1)";
3267+
match pg().verified_stmt(sql) {
3268+
Statement::CreateIndex(CreateIndex {
3269+
unique,
3270+
concurrently,
3271+
r#async,
3272+
..
3273+
}) => {
3274+
assert!(unique);
3275+
assert!(!concurrently);
3276+
assert!(r#async);
3277+
}
3278+
_ => unreachable!(),
3279+
}
3280+
}
3281+
32203282
#[test]
32213283
fn parse_create_index_with_predicate() {
32223284
let sql = "CREATE INDEX IF NOT EXISTS my_index ON my_table(col1, col2) WHERE col3 IS NULL";
@@ -3228,6 +3290,7 @@ fn parse_create_index_with_predicate() {
32283290
columns,
32293291
unique,
32303292
concurrently,
3293+
r#async,
32313294
if_not_exists,
32323295
include,
32333296
nulls_distinct: None,
@@ -3241,6 +3304,7 @@ fn parse_create_index_with_predicate() {
32413304
assert_eq!(None, using);
32423305
assert!(!unique);
32433306
assert!(!concurrently);
3307+
assert!(!r#async);
32443308
assert!(if_not_exists);
32453309
assert_eq_vec(&["col1", "col2"], &columns);
32463310
assert!(include.is_empty());
@@ -3263,6 +3327,7 @@ fn parse_create_index_with_include() {
32633327
columns,
32643328
unique,
32653329
concurrently,
3330+
r#async,
32663331
if_not_exists,
32673332
include,
32683333
nulls_distinct: None,
@@ -3276,6 +3341,7 @@ fn parse_create_index_with_include() {
32763341
assert_eq!(None, using);
32773342
assert!(!unique);
32783343
assert!(!concurrently);
3344+
assert!(!r#async);
32793345
assert!(if_not_exists);
32803346
assert_eq_vec(&["col1", "col2"], &columns);
32813347
assert_eq_vec(&["col3", "col4"], &include);
@@ -3298,6 +3364,7 @@ fn parse_create_index_with_nulls_distinct() {
32983364
columns,
32993365
unique,
33003366
concurrently,
3367+
r#async,
33013368
if_not_exists,
33023369
include,
33033370
nulls_distinct: Some(nulls_distinct),
@@ -3311,6 +3378,7 @@ fn parse_create_index_with_nulls_distinct() {
33113378
assert_eq!(None, using);
33123379
assert!(!unique);
33133380
assert!(!concurrently);
3381+
assert!(!r#async);
33143382
assert!(if_not_exists);
33153383
assert_eq_vec(&["col1", "col2"], &columns);
33163384
assert!(include.is_empty());
@@ -3331,6 +3399,7 @@ fn parse_create_index_with_nulls_distinct() {
33313399
columns,
33323400
unique,
33333401
concurrently,
3402+
r#async,
33343403
if_not_exists,
33353404
include,
33363405
nulls_distinct: Some(nulls_distinct),
@@ -3344,6 +3413,7 @@ fn parse_create_index_with_nulls_distinct() {
33443413
assert_eq!(None, using);
33453414
assert!(!unique);
33463415
assert!(!concurrently);
3416+
assert!(!r#async);
33473417
assert!(if_not_exists);
33483418
assert_eq_vec(&["col1", "col2"], &columns);
33493419
assert!(include.is_empty());

0 commit comments

Comments
 (0)