diff --git a/src/ast/mod.rs b/src/ast/mod.rs index ac429ee32..0810a41f2 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1192,6 +1192,7 @@ pub enum Statement { /// index name name: ObjectName, table_name: ObjectName, + using: Option, columns: Vec, unique: bool, if_not_exists: bool, @@ -2115,18 +2116,24 @@ impl fmt::Display for Statement { Statement::CreateIndex { name, table_name, + using, columns, unique, if_not_exists, - } => write!( - f, - "CREATE {unique}INDEX {if_not_exists}{name} ON {table_name}({columns})", - unique = if *unique { "UNIQUE " } else { "" }, - if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }, - name = name, - table_name = table_name, - columns = display_separated(columns, ",") - ), + } => { + write!( + f, + "CREATE {unique}INDEX {if_not_exists}{name} ON {table_name}", + unique = if *unique { "UNIQUE " } else { "" }, + if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }, + name = name, + table_name = table_name + )?; + if let Some(value) = using { + write!(f, " USING {} ", value)?; + } + write!(f, "({})", display_separated(columns, ",")) + } Statement::CreateRole { names, if_not_exists, diff --git a/src/parser.rs b/src/parser.rs index 393c17a14..1c71dadf0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2749,12 +2749,18 @@ impl<'a> Parser<'a> { let index_name = self.parse_object_name()?; self.expect_keyword(Keyword::ON)?; let table_name = self.parse_object_name()?; + let using = if self.expect_keyword(Keyword::USING).is_ok() { + Some(self.parse_identifier()?) + } else { + None + }; self.expect_token(&Token::LParen)?; let columns = self.parse_comma_separated(Parser::parse_order_by_expr)?; self.expect_token(&Token::RParen)?; Ok(Statement::CreateIndex { name: index_name, table_name, + using, columns, unique, if_not_exists, diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index f65c3813e..1bf261041 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -5162,9 +5162,45 @@ fn parse_create_index() { columns, unique, if_not_exists, + .. + } => { + assert_eq!("idx_name", name.to_string()); + assert_eq!("test", table_name.to_string()); + assert_eq!(indexed_columns, columns); + assert!(unique); + assert!(if_not_exists) + } + _ => unreachable!(), + } +} + +#[test] +fn test_create_index_with_using_function() { + let sql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_name ON test USING btree (name,age DESC)"; + let indexed_columns = vec![ + OrderByExpr { + expr: Expr::Identifier(Ident::new("name")), + asc: None, + nulls_first: None, + }, + OrderByExpr { + expr: Expr::Identifier(Ident::new("age")), + asc: Some(false), + nulls_first: None, + }, + ]; + match verified_stmt(sql) { + Statement::CreateIndex { + name, + table_name, + using, + columns, + unique, + if_not_exists, } => { assert_eq!("idx_name", name.to_string()); assert_eq!("test", table_name.to_string()); + assert_eq!("btree", using.unwrap().to_string()); assert_eq!(indexed_columns, columns); assert!(unique); assert!(if_not_exists)