Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2818,6 +2818,8 @@ pub struct CreateIndex {
pub unique: bool,
/// whether the index is created concurrently
pub concurrently: bool,
/// whether the index is created asynchronously
pub r#async: bool,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a link to the postgres docs describing the syntax?

/// IF NOT EXISTS clause
pub if_not_exists: bool,
/// INCLUDE clause: <https://www.postgresql.org/docs/current/sql-createindex.html>
Expand All @@ -2843,13 +2845,14 @@ impl fmt::Display for CreateIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE {unique}INDEX {concurrently}{if_not_exists}",
"CREATE {unique}INDEX {concurrently}{async_}{if_not_exists}",
unique = if self.unique { "UNIQUE " } else { "" },
concurrently = if self.concurrently {
"CONCURRENTLY "
} else {
""
},
async_ = if self.r#async { "ASYNC " } else { "" },
if_not_exists = if self.if_not_exists {
"IF NOT EXISTS "
} else {
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ impl Spanned for CreateIndex {
columns,
unique: _, // bool
concurrently: _, // bool
r#async: _, // bool
if_not_exists: _, // bool
include,
nulls_distinct: _, // bool
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ define_keywords!(
ASOF,
ASSERT,
ASYMMETRIC,
ASYNC,
AT,
ATOMIC,
ATTACH,
Expand Down
2 changes: 2 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8029,6 +8029,7 @@ impl<'a> Parser<'a> {
/// Parse a `CREATE INDEX` statement.
pub fn parse_create_index(&mut self, unique: bool) -> Result<CreateIndex, ParserError> {
let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
let r#async = self.parse_keyword(Keyword::ASYNC);
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);

let mut using = None;
Expand Down Expand Up @@ -8108,6 +8109,7 @@ impl<'a> Parser<'a> {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct,
Expand Down
4 changes: 4 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9541,6 +9541,7 @@ fn test_create_index_with_using_function() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -9555,6 +9556,7 @@ fn test_create_index_with_using_function() {
assert_eq!(indexed_columns, columns);
assert!(unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert!(include.is_empty());
assert!(with.is_empty());
Expand Down Expand Up @@ -9596,6 +9598,7 @@ fn test_create_index_with_with_clause() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -9609,6 +9612,7 @@ fn test_create_index_with_with_clause() {
pretty_assertions::assert_eq!(indexed_columns, columns);
assert!(unique);
assert!(!concurrently);
assert!(!r#async);
assert!(!if_not_exists);
assert!(include.is_empty());
pretty_assertions::assert_eq!(with_parameters, with);
Expand Down
70 changes: 70 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2806,6 +2806,7 @@ fn parse_create_index() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
nulls_distinct: None,
include,
Expand All @@ -2819,6 +2820,7 @@ fn parse_create_index() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand All @@ -2841,6 +2843,7 @@ fn parse_create_anonymous_index() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -2854,6 +2857,7 @@ fn parse_create_anonymous_index() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(!if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand Down Expand Up @@ -2959,6 +2963,7 @@ fn parse_create_indices_with_operator_classes() {
columns,
unique: false,
concurrently: false,
r#async: false,
if_not_exists: false,
include,
nulls_distinct: None,
Expand Down Expand Up @@ -2987,6 +2992,7 @@ fn parse_create_indices_with_operator_classes() {
columns,
unique: false,
concurrently: false,
r#async: false,
if_not_exists: false,
include,
nulls_distinct: None,
Expand Down Expand Up @@ -3070,6 +3076,7 @@ fn parse_create_bloom() {
columns,
unique: false,
concurrently: false,
r#async: false,
if_not_exists: false,
include,
nulls_distinct: None,
Expand Down Expand Up @@ -3126,6 +3133,7 @@ fn parse_create_brin() {
columns,
unique: false,
concurrently: false,
r#async: false,
if_not_exists: false,
include,
nulls_distinct: None,
Expand Down Expand Up @@ -3193,6 +3201,7 @@ fn parse_create_index_concurrently() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -3206,6 +3215,7 @@ fn parse_create_index_concurrently() {
assert_eq!(None, using);
assert!(!unique);
assert!(concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand All @@ -3217,6 +3227,58 @@ fn parse_create_index_concurrently() {
}
}

#[test]
fn parse_create_index_async() {
let sql = "CREATE INDEX ASYNC my_index ON my_table(col1)";
match pg().verified_stmt(sql) {
Statement::CreateIndex(CreateIndex {
name: Some(ObjectName(name)),
table_name: ObjectName(table_name),
using,
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
with,
predicate: None,
index_options,
alter_options,
}) => {
assert_eq_vec(&["my_index"], &name);
assert_eq_vec(&["my_table"], &table_name);
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(r#async);
assert!(!if_not_exists);
assert_eq_vec(&["col1"], &columns);
assert!(include.is_empty());
assert!(with.is_empty());
assert!(index_options.is_empty());
assert!(alter_options.is_empty());
}
_ => unreachable!(),
}
Comment on lines +3232 to +3264
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let sql = "CREATE INDEX ASYNC my_index ON my_table(col1)";
match pg().verified_stmt(sql) {
Statement::CreateIndex(CreateIndex {
name: Some(ObjectName(name)),
table_name: ObjectName(table_name),
using,
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
with,
predicate: None,
index_options,
alter_options,
}) => {
assert_eq_vec(&["my_index"], &name);
assert_eq_vec(&["my_table"], &table_name);
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(r#async);
assert!(!if_not_exists);
assert_eq_vec(&["col1"], &columns);
assert!(include.is_empty());
assert!(with.is_empty());
assert!(index_options.is_empty());
assert!(alter_options.is_empty());
}
_ => unreachable!(),
}
pg().verified_stmt("CREATE INDEX ASYNC my_index ON my_table(col1)");

same for the unique one. Since the flag is already asserted in other tests, a simple round trip test scenario should suffice.

Also can we move this test to common.rs - since its not guarded specifically to postgres


let sql = "CREATE UNIQUE INDEX ASYNC my_index ON my_table(col1)";
match pg().verified_stmt(sql) {
Statement::CreateIndex(CreateIndex {
unique,
concurrently,
r#async,
..
}) => {
assert!(unique);
assert!(!concurrently);
assert!(r#async);
}
_ => unreachable!(),
}
}

#[test]
fn parse_create_index_with_predicate() {
let sql = "CREATE INDEX IF NOT EXISTS my_index ON my_table(col1, col2) WHERE col3 IS NULL";
Expand All @@ -3228,6 +3290,7 @@ fn parse_create_index_with_predicate() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -3241,6 +3304,7 @@ fn parse_create_index_with_predicate() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand All @@ -3263,6 +3327,7 @@ fn parse_create_index_with_include() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: None,
Expand All @@ -3276,6 +3341,7 @@ fn parse_create_index_with_include() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert_eq_vec(&["col3", "col4"], &include);
Expand All @@ -3298,6 +3364,7 @@ fn parse_create_index_with_nulls_distinct() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: Some(nulls_distinct),
Expand All @@ -3311,6 +3378,7 @@ fn parse_create_index_with_nulls_distinct() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand All @@ -3331,6 +3399,7 @@ fn parse_create_index_with_nulls_distinct() {
columns,
unique,
concurrently,
r#async,
if_not_exists,
include,
nulls_distinct: Some(nulls_distinct),
Expand All @@ -3344,6 +3413,7 @@ fn parse_create_index_with_nulls_distinct() {
assert_eq!(None, using);
assert!(!unique);
assert!(!concurrently);
assert!(!r#async);
assert!(if_not_exists);
assert_eq_vec(&["col1", "col2"], &columns);
assert!(include.is_empty());
Expand Down
Loading