@@ -6868,9 +6868,7 @@ impl<'a> Parser<'a> {
68686868 None
68696869 };
68706870
6871- self.expect_token(&Token::LParen)?;
6872- let columns = self.parse_comma_separated(Parser::parse_create_index_expr)?;
6873- self.expect_token(&Token::RParen)?;
6871+ let columns = self.parse_parenthesized_index_column_list()?;
68746872
68756873 let include = if self.parse_keyword(Keyword::INCLUDE) {
68766874 self.expect_token(&Token::LParen)?;
@@ -7626,9 +7624,22 @@ impl<'a> Parser<'a> {
76267624 }
76277625
76287626 pub fn parse_procedure_param(&mut self) -> Result<ProcedureParam, ParserError> {
7627+ let mode = if self.parse_keyword(Keyword::IN) {
7628+ Some(ArgMode::In)
7629+ } else if self.parse_keyword(Keyword::OUT) {
7630+ Some(ArgMode::Out)
7631+ } else if self.parse_keyword(Keyword::INOUT) {
7632+ Some(ArgMode::InOut)
7633+ } else {
7634+ None
7635+ };
76297636 let name = self.parse_identifier()?;
76307637 let data_type = self.parse_data_type()?;
7631- Ok(ProcedureParam { name, data_type })
7638+ Ok(ProcedureParam {
7639+ name,
7640+ data_type,
7641+ mode,
7642+ })
76327643 }
76337644
76347645 pub fn parse_column_def(&mut self) -> Result<ColumnDef, ParserError> {
@@ -8070,7 +8081,7 @@ impl<'a> Parser<'a> {
80708081 let index_name = self.parse_optional_ident()?;
80718082 let index_type = self.parse_optional_using_then_index_type()?;
80728083
8073- let columns = self.parse_parenthesized_column_list(Mandatory, false )?;
8084+ let columns = self.parse_parenthesized_index_column_list( )?;
80748085 let index_options = self.parse_index_options()?;
80758086 let characteristics = self.parse_constraint_characteristics()?;
80768087 Ok(Some(TableConstraint::Unique {
@@ -8092,7 +8103,7 @@ impl<'a> Parser<'a> {
80928103 let index_name = self.parse_optional_ident()?;
80938104 let index_type = self.parse_optional_using_then_index_type()?;
80948105
8095- let columns = self.parse_parenthesized_column_list(Mandatory, false )?;
8106+ let columns = self.parse_parenthesized_index_column_list( )?;
80968107 let index_options = self.parse_index_options()?;
80978108 let characteristics = self.parse_constraint_characteristics()?;
80988109 Ok(Some(TableConstraint::PrimaryKey {
@@ -8170,7 +8181,7 @@ impl<'a> Parser<'a> {
81708181 };
81718182
81728183 let index_type = self.parse_optional_using_then_index_type()?;
8173- let columns = self.parse_parenthesized_column_list(Mandatory, false )?;
8184+ let columns = self.parse_parenthesized_index_column_list( )?;
81748185
81758186 Ok(Some(TableConstraint::Index {
81768187 display_as_key,
@@ -8199,7 +8210,7 @@ impl<'a> Parser<'a> {
81998210
82008211 let opt_index_name = self.parse_optional_ident()?;
82018212
8202- let columns = self.parse_parenthesized_column_list(Mandatory, false )?;
8213+ let columns = self.parse_parenthesized_index_column_list( )?;
82038214
82048215 Ok(Some(TableConstraint::FulltextOrSpatial {
82058216 fulltext,
@@ -10601,6 +10612,14 @@ impl<'a> Parser<'a> {
1060110612 self.parse_parenthesized_column_list_inner(optional, allow_empty, |p| p.parse_identifier())
1060210613 }
1060310614
10615+ /// Parses a parenthesized comma-separated list of index columns, which can be arbitrary
10616+ /// expressions with ordering information (and an opclass in some dialects).
10617+ fn parse_parenthesized_index_column_list(&mut self) -> Result<Vec<IndexColumn>, ParserError> {
10618+ self.parse_parenthesized_column_list_inner(Mandatory, false, |p| {
10619+ p.parse_create_index_expr()
10620+ })
10621+ }
10622+
1060410623 /// Parses a parenthesized comma-separated list of qualified, possibly quoted identifiers.
1060510624 /// For example: `(db1.sc1.tbl1.col1, db1.sc1.tbl1."col 2", ...)`
1060610625 pub fn parse_parenthesized_qualified_column_list(
@@ -15017,7 +15036,8 @@ impl<'a> Parser<'a> {
1501715036
1501815037 /// Parse a FETCH clause
1501915038 pub fn parse_fetch(&mut self) -> Result<Fetch, ParserError> {
15020- self.expect_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT])?;
15039+ let _ = self.parse_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT]);
15040+
1502115041 let (quantity, percent) = if self
1502215042 .parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])
1502315043 .is_some()
@@ -15026,16 +15046,16 @@ impl<'a> Parser<'a> {
1502615046 } else {
1502715047 let quantity = Expr::Value(self.parse_value()?);
1502815048 let percent = self.parse_keyword(Keyword::PERCENT);
15029- self.expect_one_of_keywords (&[Keyword::ROW, Keyword::ROWS])? ;
15049+ let _ = self.parse_one_of_keywords (&[Keyword::ROW, Keyword::ROWS]);
1503015050 (Some(quantity), percent)
1503115051 };
15052+
1503215053 let with_ties = if self.parse_keyword(Keyword::ONLY) {
1503315054 false
15034- } else if self.parse_keywords(&[Keyword::WITH, Keyword::TIES]) {
15035- true
1503615055 } else {
15037- return self.expected("one of ONLY or WITH TIES", self.peek_token());
15056+ self.parse_keywords(&[Keyword:: WITH, Keyword::TIES])
1503815057 };
15058+
1503915059 Ok(Fetch {
1504015060 with_ties,
1504115061 percent,
@@ -16527,6 +16547,20 @@ mod tests {
1652716547 }};
1652816548 }
1652916549
16550+ fn mk_expected_col(name: &str) -> IndexColumn {
16551+ IndexColumn {
16552+ column: OrderByExpr {
16553+ expr: Expr::Identifier(name.into()),
16554+ options: OrderByOptions {
16555+ asc: None,
16556+ nulls_first: None,
16557+ },
16558+ with_fill: None,
16559+ },
16560+ operator_class: None,
16561+ }
16562+ }
16563+
1653016564 let dialect =
1653116565 TestedDialects::new(vec![Box::new(GenericDialect {}), Box::new(MySqlDialect {})]);
1653216566
@@ -16537,7 +16571,7 @@ mod tests {
1653716571 display_as_key: false,
1653816572 name: None,
1653916573 index_type: None,
16540- columns: vec![Ident::new ("c1")],
16574+ columns: vec![mk_expected_col ("c1")],
1654116575 }
1654216576 );
1654316577
@@ -16548,7 +16582,7 @@ mod tests {
1654816582 display_as_key: true,
1654916583 name: None,
1655016584 index_type: None,
16551- columns: vec![Ident::new ("c1")],
16585+ columns: vec![mk_expected_col ("c1")],
1655216586 }
1655316587 );
1655416588
@@ -16559,7 +16593,7 @@ mod tests {
1655916593 display_as_key: false,
1656016594 name: Some(Ident::with_quote('\'', "index")),
1656116595 index_type: None,
16562- columns: vec![Ident::new ("c1"), Ident::new ("c2")],
16596+ columns: vec![mk_expected_col ("c1"), mk_expected_col ("c2")],
1656316597 }
1656416598 );
1656516599
@@ -16570,7 +16604,7 @@ mod tests {
1657016604 display_as_key: false,
1657116605 name: None,
1657216606 index_type: Some(IndexType::BTree),
16573- columns: vec![Ident::new ("c1")],
16607+ columns: vec![mk_expected_col ("c1")],
1657416608 }
1657516609 );
1657616610
@@ -16581,7 +16615,7 @@ mod tests {
1658116615 display_as_key: false,
1658216616 name: None,
1658316617 index_type: Some(IndexType::Hash),
16584- columns: vec![Ident::new ("c1")],
16618+ columns: vec![mk_expected_col ("c1")],
1658516619 }
1658616620 );
1658716621
@@ -16592,7 +16626,7 @@ mod tests {
1659216626 display_as_key: false,
1659316627 name: Some(Ident::new("idx_name")),
1659416628 index_type: Some(IndexType::BTree),
16595- columns: vec![Ident::new ("c1")],
16629+ columns: vec![mk_expected_col ("c1")],
1659616630 }
1659716631 );
1659816632
@@ -16603,7 +16637,7 @@ mod tests {
1660316637 display_as_key: false,
1660416638 name: Some(Ident::new("idx_name")),
1660516639 index_type: Some(IndexType::Hash),
16606- columns: vec![Ident::new ("c1")],
16640+ columns: vec![mk_expected_col ("c1")],
1660716641 }
1660816642 );
1660916643 }
0 commit comments