From 3c08e08fb0733f5fece629836f2224fdac7ddb33 Mon Sep 17 00:00:00 2001 From: yangjiaxin Date: Mon, 28 Nov 2022 15:48:12 +0800 Subject: [PATCH 1/2] fix: create index using function --- src/ast/mod.rs | 25 ++++++++++++++++--------- src/parser.rs | 6 ++++++ tests/sqlparser_common.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f568c3960..4c667870f 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1157,6 +1157,7 @@ pub enum Statement { /// index name name: ObjectName, table_name: ObjectName, + using: Option, columns: Vec, unique: bool, if_not_exists: bool, @@ -2075,18 +2076,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 8361e02ad..cd1fe3e74 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2695,12 +2695,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 ec4c2f257..d5c0e2af6 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -5052,9 +5052,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) @@ -5063,6 +5099,7 @@ fn parse_create_index() { } } + #[test] fn parse_drop_index() { let sql = "DROP INDEX idx_a"; From 38f36341dd8876b86beb88fed7faa58d89df166d Mon Sep 17 00:00:00 2001 From: yangjiaxin Date: Mon, 28 Nov 2022 15:59:19 +0800 Subject: [PATCH 2/2] fix: code style --- src/ast/mod.rs | 2 +- src/parser.rs | 2 +- tests/sqlparser_common.rs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4c667870f..7ba341d3c 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2093,7 +2093,7 @@ impl fmt::Display for Statement { 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 cd1fe3e74..c4beb1492 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2697,7 +2697,7 @@ impl<'a> Parser<'a> { let table_name = self.parse_object_name()?; let using = if self.expect_keyword(Keyword::USING).is_ok() { Some(self.parse_identifier()?) - }else { + } else { None }; self.expect_token(&Token::LParen)?; diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index d5c0e2af6..89ea056db 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -5099,7 +5099,6 @@ fn test_create_index_with_using_function() { } } - #[test] fn parse_drop_index() { let sql = "DROP INDEX idx_a";