From 4452f9bad1ce27e6149e38eb61a4883cd85e78b2 Mon Sep 17 00:00:00 2001 From: mz Date: Thu, 30 Jul 2020 20:37:58 +0800 Subject: [PATCH] Support specifying ASC/DESC in index columns (#249) ...by reusing `OrderByExpr` for `columns` in `Statement::CreateIndex`. This supports SQLite's indexed-column syntax https://www.sqlite.org/syntax/indexed-column.html MSSQL's (`ON ( column [ ASC | DESC ] [ ,...n ] )`) https://docs.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-ver15 And most of PostgreSQL syntax (except for opclass): `( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )` https://www.postgresql.org/docs/12/sql-createindex.html --- src/ast/mod.rs | 2 +- src/parser.rs | 4 +++- tests/sqlparser_common.rs | 17 ++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 3c2f5c4f..865577ca 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -498,7 +498,7 @@ pub enum Statement { /// index name name: ObjectName, table_name: ObjectName, - columns: Vec, + columns: Vec, unique: bool, if_not_exists: bool, }, diff --git a/src/parser.rs b/src/parser.rs index 320cb4f5..b58bdc5c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1142,7 +1142,9 @@ impl Parser { let index_name = self.parse_object_name()?; self.expect_keyword(Keyword::ON)?; let table_name = self.parse_object_name()?; - let columns = self.parse_parenthesized_column_list(Mandatory)?; + 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, diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 54da1bc0..1a1c3ad8 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -3152,8 +3152,19 @@ fn ensure_multiple_dialects_are_tested() { #[test] fn parse_create_index() { - let sql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_name ON test(name,age)"; - let ident_vec = vec![Ident::new("name"), Ident::new("age")]; + let sql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_name ON test(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, @@ -3164,7 +3175,7 @@ fn parse_create_index() { } => { assert_eq!("idx_name", name.to_string()); assert_eq!("test", table_name.to_string()); - assert_eq!(ident_vec, columns); + assert_eq!(indexed_columns, columns); assert_eq!(true, unique); assert_eq!(true, if_not_exists) }