@@ -6407,10 +6407,7 @@ impl<'a> Parser<'a> {
64076407 } else {
64086408 None
64096409 };
6410- self.expect_token(&Token::LParen)?;
6411- let columns = self.parse_comma_separated(Parser::parse_order_by_expr)?;
6412- self.expect_token(&Token::RParen)?;
6413-
6410+ let columns = self.parse_index_exprs()?;
64146411 let include = if self.parse_keyword(Keyword::INCLUDE) {
64156412 self.expect_token(&Token::LParen)?;
64166413 let columns = self.parse_comma_separated(|p| p.parse_identifier())?;
@@ -7439,7 +7436,6 @@ impl<'a> Parser<'a> {
74397436 // optional index name
74407437 let index_name = self.parse_optional_indent()?;
74417438 let index_type = self.parse_optional_using_then_index_type()?;
7442-
74437439 let index_exprs = self.parse_index_exprs()?;
74447440 let index_options = self.parse_index_options()?;
74457441 let characteristics = self.parse_constraint_characteristics()?;
@@ -7646,10 +7642,14 @@ impl<'a> Parser<'a> {
76467642 }
76477643 }
76487644
7645+ /// Parse index expressions, like:
7646+ /// `(column_name [COLLATE collation] [opclass [ ( opclass_parameter = value [, ... ] )] [ASC | DESC] [NULLS {FIRST | LAST}]] [, ... ])`
76497647 pub fn parse_index_exprs(&mut self) -> Result<Vec<IndexExpr>, ParserError> {
76507648 self.parse_parenthesized(|p| p.parse_comma_separated(Parser::parse_index_expr))
76517649 }
76527650
7651+ /// Parse index expression, like:
7652+ /// `column_name [COLLATE collation] [opclass [ ( opclass_parameter = value [, ... ] )] [ASC | DESC] [NULLS {FIRST | LAST}]`
76537653 pub fn parse_index_expr(&mut self) -> Result<IndexExpr, ParserError> {
76547654 let expr = self.parse_expr()?;
76557655 let collation = if self.parse_keyword(Keyword::COLLATE) {
@@ -7658,27 +7658,47 @@ impl<'a> Parser<'a> {
76587658 None
76597659 };
76607660
7661- let (operator_class, order_options ) = if self.peek_keyword(Keyword::ASC)
7661+ let (opclass, sort_options ) = if self.peek_keyword(Keyword::ASC)
76627662 || self.peek_keyword(Keyword::DESC)
76637663 || self.peek_keyword(Keyword::NULLS)
76647664 {
7665- let order_options = self.parse_order_by_options()?;
7666- (None, order_options )
7665+ let sort_options = self.parse_order_by_options()?;
7666+ (None, sort_options )
76677667 } else {
7668- let operator_class = self.maybe_parse(|p| p.parse_expr ())?;
7668+ let opclass = self.maybe_parse(|p| p.parse_operator_class ())?;
76697669
7670- let order_options = self.parse_order_by_options()?;
7671- (operator_class, order_options )
7670+ let sort_options = self.parse_order_by_options()?;
7671+ (opclass, sort_options )
76727672 };
76737673
76747674 Ok(IndexExpr {
76757675 expr,
76767676 collation,
7677- operator_class ,
7678- order_options ,
7677+ opclass ,
7678+ sort_options ,
76797679 })
76807680 }
76817681
7682+ fn parse_operator_class(&mut self) -> Result<OperatorClass, ParserError> {
7683+ let name = self.parse_identifier()?;
7684+ let parameters = if self.peek_token() == Token::LParen {
7685+ self.parse_parenthesized(|p| {
7686+ p.parse_comma_separated(Parser::parse_operator_class_param)
7687+ })?
7688+ } else {
7689+ vec![]
7690+ };
7691+
7692+ Ok(OperatorClass { name, parameters })
7693+ }
7694+
7695+ fn parse_operator_class_param(&mut self) -> Result<OperatorClassParameter, ParserError> {
7696+ let name = self.parse_identifier()?;
7697+ self.expect_token(&Token::Eq)?;
7698+ let value = self.parse_expr()?;
7699+ Ok(OperatorClassParameter { name, value })
7700+ }
7701+
76827702 /// Parse `[ident]`, mostly `ident` is name, like:
76837703 /// `window_name`, `index_name`, ...
76847704 pub fn parse_optional_indent(&mut self) -> Result<Option<Ident>, ParserError> {
@@ -14721,8 +14741,6 @@ impl Word {
1472114741
1472214742#[cfg(test)]
1472314743mod tests {
14724- use std::vec;
14725-
1472614744 use crate::test_utils::{all_dialects, TestedDialects};
1472714745
1472814746 use super::*;
@@ -15176,8 +15194,8 @@ mod tests {
1517615194 index_exprs: vec![IndexExpr {
1517715195 expr: Expr::Identifier(Ident::new("c1")),
1517815196 collation: None,
15179- operator_class : None,
15180- order_options : OrderByOptions {
15197+ opclass : None,
15198+ sort_options : OrderByOptions {
1518115199 asc: None,
1518215200 nulls_first: None,
1518315201 },
@@ -15195,8 +15213,8 @@ mod tests {
1519515213 index_exprs: vec![IndexExpr {
1519615214 expr: Expr::Identifier(Ident::new("c1")),
1519715215 collation: None,
15198- operator_class : None,
15199- order_options : OrderByOptions {
15216+ opclass : None,
15217+ sort_options : OrderByOptions {
1520015218 asc: None,
1520115219 nulls_first: None,
1520215220 },
@@ -15215,17 +15233,17 @@ mod tests {
1521515233 IndexExpr {
1521615234 expr: Expr::Identifier(Ident::new("c1")),
1521715235 collation: None,
15218- operator_class : None,
15219- order_options : OrderByOptions {
15236+ opclass : None,
15237+ sort_options : OrderByOptions {
1522015238 asc: None,
1522115239 nulls_first: None,
1522215240 },
1522315241 },
1522415242 IndexExpr {
1522515243 expr: Expr::Identifier(Ident::new("c2")),
1522615244 collation: None,
15227- operator_class : None,
15228- order_options : OrderByOptions {
15245+ opclass : None,
15246+ sort_options : OrderByOptions {
1522915247 asc: None,
1523015248 nulls_first: None,
1523115249 },
@@ -15244,8 +15262,8 @@ mod tests {
1524415262 index_exprs: vec![IndexExpr {
1524515263 expr: Expr::Identifier(Ident::new("c1")),
1524615264 collation: None,
15247- operator_class : None,
15248- order_options : OrderByOptions {
15265+ opclass : None,
15266+ sort_options : OrderByOptions {
1524915267 asc: None,
1525015268 nulls_first: None,
1525115269 },
@@ -15263,8 +15281,8 @@ mod tests {
1526315281 index_exprs: vec![IndexExpr {
1526415282 expr: Expr::Identifier(Ident::new("c1")),
1526515283 collation: None,
15266- operator_class : None,
15267- order_options : OrderByOptions {
15284+ opclass : None,
15285+ sort_options : OrderByOptions {
1526815286 asc: None,
1526915287 nulls_first: None,
1527015288 },
@@ -15282,8 +15300,8 @@ mod tests {
1528215300 index_exprs: vec![IndexExpr {
1528315301 expr: Expr::Identifier(Ident::new("c1")),
1528415302 collation: None,
15285- operator_class : None,
15286- order_options : OrderByOptions {
15303+ opclass : None,
15304+ sort_options : OrderByOptions {
1528715305 asc: None,
1528815306 nulls_first: None,
1528915307 },
@@ -15301,8 +15319,8 @@ mod tests {
1530115319 index_exprs: vec![IndexExpr {
1530215320 expr: Expr::Identifier(Ident::new("c1")),
1530315321 collation: None,
15304- operator_class : None,
15305- order_options : OrderByOptions {
15322+ opclass : None,
15323+ sort_options : OrderByOptions {
1530615324 asc: None,
1530715325 nulls_first: None,
1530815326 },
@@ -15319,49 +15337,25 @@ mod tests {
1531915337 index_type: None,
1532015338 index_exprs: vec![
1532115339 IndexExpr {
15322- expr: Expr::Function(Function {
15323- name: ObjectName::from(vec![Ident::new("c1")]),
15324- uses_odbc_syntax: false,
15325- parameters: FunctionArguments::None,
15326- args: FunctionArguments::List(FunctionArgumentList {
15327- duplicate_treatment: None,
15328- args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
15329- Expr::Value(crate::test_utils::number("10"))
15330- )),],
15331- clauses: vec![],
15332- }),
15333- filter: None,
15334- null_treatment: None,
15335- over: None,
15336- within_group: vec![],
15337- }),
15340+ expr: crate::test_utils::call(
15341+ "c1",
15342+ [Expr::Value(crate::test_utils::number("10"))]
15343+ ),
1533815344 collation: None,
15339- operator_class : None,
15340- order_options : OrderByOptions {
15345+ opclass : None,
15346+ sort_options : OrderByOptions {
1534115347 asc: None,
1534215348 nulls_first: None,
1534315349 },
1534415350 },
1534515351 IndexExpr {
15346- expr: Expr::Nested(Box::new(Expr::Function(Function {
15347- name: ObjectName::from(vec![Ident::new("LOWER")]),
15348- uses_odbc_syntax: false,
15349- parameters: FunctionArguments::None,
15350- args: FunctionArguments::List(FunctionArgumentList {
15351- duplicate_treatment: None,
15352- args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
15353- Expr::Identifier(Ident::new("c2"))
15354- )),],
15355- clauses: vec![],
15356- }),
15357- filter: None,
15358- null_treatment: None,
15359- over: None,
15360- within_group: vec![],
15361- }))),
15352+ expr: Expr::Nested(Box::new(crate::test_utils::call(
15353+ "LOWER",
15354+ [Expr::Identifier(Ident::new("c2"))]
15355+ ))),
1536215356 collation: None,
15363- operator_class : None,
15364- order_options : OrderByOptions {
15357+ opclass : None,
15358+ sort_options : OrderByOptions {
1536515359 asc: Some(false),
1536615360 nulls_first: None,
1536715361 }
0 commit comments