Skip to content

Commit 9f4bb86

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 272c25e commit 9f4bb86

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
@@ -2808,6 +2808,8 @@ pub struct CreateIndex {
28082808
pub unique: bool,
28092809
/// whether the index is created concurrently
28102810
pub concurrently: bool,
2811+
/// whether the index is created asynchronously
2812+
pub r#async: bool,
28112813
/// IF NOT EXISTS clause
28122814
pub if_not_exists: bool,
28132815
/// INCLUDE clause: <https://www.postgresql.org/docs/current/sql-createindex.html>
@@ -2833,13 +2835,14 @@ impl fmt::Display for CreateIndex {
28332835
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28342836
write!(
28352837
f,
2836-
"CREATE {unique}INDEX {concurrently}{if_not_exists}",
2838+
"CREATE {unique}INDEX {concurrently}{async_}{if_not_exists}",
28372839
unique = if self.unique { "UNIQUE " } else { "" },
28382840
concurrently = if self.concurrently {
28392841
"CONCURRENTLY "
28402842
} else {
28412843
""
28422844
},
2845+
async_ = if self.r#async { "ASYNC " } else { "" },
28432846
if_not_exists = if self.if_not_exists {
28442847
"IF NOT EXISTS "
28452848
} else {

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ impl Spanned for CreateIndex {
664664
columns,
665665
unique: _, // bool
666666
concurrently: _, // bool
667+
r#async: _, // bool
667668
if_not_exists: _, // bool
668669
include,
669670
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
@@ -7763,6 +7763,7 @@ impl<'a> Parser<'a> {
77637763
/// Parse a `CREATE INDEX` statement.
77647764
pub fn parse_create_index(&mut self, unique: bool) -> Result<CreateIndex, ParserError> {
77657765
let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
7766+
let r#async = self.parse_keyword(Keyword::ASYNC);
77667767
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
77677768

77687769
let mut using = None;
@@ -7842,6 +7843,7 @@ impl<'a> Parser<'a> {
78427843
columns,
78437844
unique,
78447845
concurrently,
7846+
r#async,
78457847
if_not_exists,
78467848
include,
78477849
nulls_distinct,

tests/sqlparser_common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9467,6 +9467,7 @@ fn test_create_index_with_using_function() {
94679467
columns,
94689468
unique,
94699469
concurrently,
9470+
r#async,
94709471
if_not_exists,
94719472
include,
94729473
nulls_distinct: None,
@@ -9481,6 +9482,7 @@ fn test_create_index_with_using_function() {
94819482
assert_eq!(indexed_columns, columns);
94829483
assert!(unique);
94839484
assert!(!concurrently);
9485+
assert!(!r#async);
94849486
assert!(if_not_exists);
94859487
assert!(include.is_empty());
94869488
assert!(with.is_empty());
@@ -9522,6 +9524,7 @@ fn test_create_index_with_with_clause() {
95229524
columns,
95239525
unique,
95249526
concurrently,
9527+
r#async,
95259528
if_not_exists,
95269529
include,
95279530
nulls_distinct: None,
@@ -9535,6 +9538,7 @@ fn test_create_index_with_with_clause() {
95359538
pretty_assertions::assert_eq!(indexed_columns, columns);
95369539
assert!(unique);
95379540
assert!(!concurrently);
9541+
assert!(!r#async);
95389542
assert!(!if_not_exists);
95399543
assert!(include.is_empty());
95409544
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
@@ -2507,6 +2507,7 @@ fn parse_create_index() {
25072507
columns,
25082508
unique,
25092509
concurrently,
2510+
r#async,
25102511
if_not_exists,
25112512
nulls_distinct: None,
25122513
include,
@@ -2520,6 +2521,7 @@ fn parse_create_index() {
25202521
assert_eq!(None, using);
25212522
assert!(!unique);
25222523
assert!(!concurrently);
2524+
assert!(!r#async);
25232525
assert!(if_not_exists);
25242526
assert_eq_vec(&["col1", "col2"], &columns);
25252527
assert!(include.is_empty());
@@ -2542,6 +2544,7 @@ fn parse_create_anonymous_index() {
25422544
columns,
25432545
unique,
25442546
concurrently,
2547+
r#async,
25452548
if_not_exists,
25462549
include,
25472550
nulls_distinct: None,
@@ -2555,6 +2558,7 @@ fn parse_create_anonymous_index() {
25552558
assert_eq!(None, using);
25562559
assert!(!unique);
25572560
assert!(!concurrently);
2561+
assert!(!r#async);
25582562
assert!(!if_not_exists);
25592563
assert_eq_vec(&["col1", "col2"], &columns);
25602564
assert!(include.is_empty());
@@ -2660,6 +2664,7 @@ fn parse_create_indices_with_operator_classes() {
26602664
columns,
26612665
unique: false,
26622666
concurrently: false,
2667+
r#async: false,
26632668
if_not_exists: false,
26642669
include,
26652670
nulls_distinct: None,
@@ -2688,6 +2693,7 @@ fn parse_create_indices_with_operator_classes() {
26882693
columns,
26892694
unique: false,
26902695
concurrently: false,
2696+
r#async: false,
26912697
if_not_exists: false,
26922698
include,
26932699
nulls_distinct: None,
@@ -2771,6 +2777,7 @@ fn parse_create_bloom() {
27712777
columns,
27722778
unique: false,
27732779
concurrently: false,
2780+
r#async: false,
27742781
if_not_exists: false,
27752782
include,
27762783
nulls_distinct: None,
@@ -2827,6 +2834,7 @@ fn parse_create_brin() {
28272834
columns,
28282835
unique: false,
28292836
concurrently: false,
2837+
r#async: false,
28302838
if_not_exists: false,
28312839
include,
28322840
nulls_distinct: None,
@@ -2894,6 +2902,7 @@ fn parse_create_index_concurrently() {
28942902
columns,
28952903
unique,
28962904
concurrently,
2905+
r#async,
28972906
if_not_exists,
28982907
include,
28992908
nulls_distinct: None,
@@ -2907,6 +2916,7 @@ fn parse_create_index_concurrently() {
29072916
assert_eq!(None, using);
29082917
assert!(!unique);
29092918
assert!(concurrently);
2919+
assert!(!r#async);
29102920
assert!(if_not_exists);
29112921
assert_eq_vec(&["col1", "col2"], &columns);
29122922
assert!(include.is_empty());
@@ -2918,6 +2928,58 @@ fn parse_create_index_concurrently() {
29182928
}
29192929
}
29202930

2931+
#[test]
2932+
fn parse_create_index_async() {
2933+
let sql = "CREATE INDEX ASYNC my_index ON my_table(col1)";
2934+
match pg().verified_stmt(sql) {
2935+
Statement::CreateIndex(CreateIndex {
2936+
name: Some(ObjectName(name)),
2937+
table_name: ObjectName(table_name),
2938+
using,
2939+
columns,
2940+
unique,
2941+
concurrently,
2942+
r#async,
2943+
if_not_exists,
2944+
include,
2945+
nulls_distinct: None,
2946+
with,
2947+
predicate: None,
2948+
index_options,
2949+
alter_options,
2950+
}) => {
2951+
assert_eq_vec(&["my_index"], &name);
2952+
assert_eq_vec(&["my_table"], &table_name);
2953+
assert_eq!(None, using);
2954+
assert!(!unique);
2955+
assert!(!concurrently);
2956+
assert!(r#async);
2957+
assert!(!if_not_exists);
2958+
assert_eq_vec(&["col1"], &columns);
2959+
assert!(include.is_empty());
2960+
assert!(with.is_empty());
2961+
assert!(index_options.is_empty());
2962+
assert!(alter_options.is_empty());
2963+
}
2964+
_ => unreachable!(),
2965+
}
2966+
2967+
let sql = "CREATE UNIQUE INDEX ASYNC my_index ON my_table(col1)";
2968+
match pg().verified_stmt(sql) {
2969+
Statement::CreateIndex(CreateIndex {
2970+
unique,
2971+
concurrently,
2972+
r#async,
2973+
..
2974+
}) => {
2975+
assert!(unique);
2976+
assert!(!concurrently);
2977+
assert!(r#async);
2978+
}
2979+
_ => unreachable!(),
2980+
}
2981+
}
2982+
29212983
#[test]
29222984
fn parse_create_index_with_predicate() {
29232985
let sql = "CREATE INDEX IF NOT EXISTS my_index ON my_table(col1, col2) WHERE col3 IS NULL";
@@ -2929,6 +2991,7 @@ fn parse_create_index_with_predicate() {
29292991
columns,
29302992
unique,
29312993
concurrently,
2994+
r#async,
29322995
if_not_exists,
29332996
include,
29342997
nulls_distinct: None,
@@ -2942,6 +3005,7 @@ fn parse_create_index_with_predicate() {
29423005
assert_eq!(None, using);
29433006
assert!(!unique);
29443007
assert!(!concurrently);
3008+
assert!(!r#async);
29453009
assert!(if_not_exists);
29463010
assert_eq_vec(&["col1", "col2"], &columns);
29473011
assert!(include.is_empty());
@@ -2964,6 +3028,7 @@ fn parse_create_index_with_include() {
29643028
columns,
29653029
unique,
29663030
concurrently,
3031+
r#async,
29673032
if_not_exists,
29683033
include,
29693034
nulls_distinct: None,
@@ -2977,6 +3042,7 @@ fn parse_create_index_with_include() {
29773042
assert_eq!(None, using);
29783043
assert!(!unique);
29793044
assert!(!concurrently);
3045+
assert!(!r#async);
29803046
assert!(if_not_exists);
29813047
assert_eq_vec(&["col1", "col2"], &columns);
29823048
assert_eq_vec(&["col3", "col4"], &include);
@@ -2999,6 +3065,7 @@ fn parse_create_index_with_nulls_distinct() {
29993065
columns,
30003066
unique,
30013067
concurrently,
3068+
r#async,
30023069
if_not_exists,
30033070
include,
30043071
nulls_distinct: Some(nulls_distinct),
@@ -3012,6 +3079,7 @@ fn parse_create_index_with_nulls_distinct() {
30123079
assert_eq!(None, using);
30133080
assert!(!unique);
30143081
assert!(!concurrently);
3082+
assert!(!r#async);
30153083
assert!(if_not_exists);
30163084
assert_eq_vec(&["col1", "col2"], &columns);
30173085
assert!(include.is_empty());
@@ -3032,6 +3100,7 @@ fn parse_create_index_with_nulls_distinct() {
30323100
columns,
30333101
unique,
30343102
concurrently,
3103+
r#async,
30353104
if_not_exists,
30363105
include,
30373106
nulls_distinct: Some(nulls_distinct),
@@ -3045,6 +3114,7 @@ fn parse_create_index_with_nulls_distinct() {
30453114
assert_eq!(None, using);
30463115
assert!(!unique);
30473116
assert!(!concurrently);
3117+
assert!(!r#async);
30483118
assert!(if_not_exists);
30493119
assert_eq_vec(&["col1", "col2"], &columns);
30503120
assert!(include.is_empty());

0 commit comments

Comments
 (0)