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 <object> ( 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
This commit is contained in:
mz 2020-07-30 20:37:58 +08:00 committed by GitHub
parent 9e7e30282e
commit 4452f9bad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 5 deletions

View file

@ -498,7 +498,7 @@ pub enum Statement {
/// index name /// index name
name: ObjectName, name: ObjectName,
table_name: ObjectName, table_name: ObjectName,
columns: Vec<Ident>, columns: Vec<OrderByExpr>,
unique: bool, unique: bool,
if_not_exists: bool, if_not_exists: bool,
}, },

View file

@ -1142,7 +1142,9 @@ impl Parser {
let index_name = self.parse_object_name()?; let index_name = self.parse_object_name()?;
self.expect_keyword(Keyword::ON)?; self.expect_keyword(Keyword::ON)?;
let table_name = self.parse_object_name()?; 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 { Ok(Statement::CreateIndex {
name: index_name, name: index_name,
table_name, table_name,

View file

@ -3152,8 +3152,19 @@ fn ensure_multiple_dialects_are_tested() {
#[test] #[test]
fn parse_create_index() { fn parse_create_index() {
let sql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_name ON test(name,age)"; let sql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_name ON test(name,age DESC)";
let ident_vec = vec![Ident::new("name"), Ident::new("age")]; 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) { match verified_stmt(sql) {
Statement::CreateIndex { Statement::CreateIndex {
name, name,
@ -3164,7 +3175,7 @@ fn parse_create_index() {
} => { } => {
assert_eq!("idx_name", name.to_string()); assert_eq!("idx_name", name.to_string());
assert_eq!("test", table_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, unique);
assert_eq!(true, if_not_exists) assert_eq!(true, if_not_exists)
} }