@@ -3965,6 +3965,18 @@ impl<'a> Parser<'a> {
39653965 true
39663966 }
39673967
3968+ /// If the current token is one of the given `keywords`, returns the keyword
3969+ /// that matches, without consuming the token. Otherwise, returns [`None`].
3970+ #[must_use]
3971+ pub fn peek_one_of_keywords(&self, keywords: &[Keyword]) -> Option<Keyword> {
3972+ for keyword in keywords {
3973+ if self.peek_keyword(*keyword) {
3974+ return Some(*keyword);
3975+ }
3976+ }
3977+ None
3978+ }
3979+
39683980 /// If the current token is one of the given `keywords`, consume the token
39693981 /// and return the keyword that matches. Otherwise, no tokens are consumed
39703982 /// and returns [`None`].
@@ -6416,12 +6428,13 @@ impl<'a> Parser<'a> {
64166428 };
64176429 let table_name = self.parse_object_name(false)?;
64186430 let using = if self.parse_keyword(Keyword::USING) {
6419- Some(self.parse_identifier ()?)
6431+ Some(self.parse_index_type ()?)
64206432 } else {
64216433 None
64226434 };
6435+
64236436 self.expect_token(&Token::LParen)?;
6424- let columns = self.parse_comma_separated(Parser::parse_order_by_expr )?;
6437+ let columns = self.parse_comma_separated(Parser::parse_create_index_expr )?;
64256438 self.expect_token(&Token::RParen)?;
64266439
64276440 let include = if self.parse_keyword(Keyword::INCLUDE) {
@@ -7639,16 +7652,30 @@ impl<'a> Parser<'a> {
76397652 }
76407653
76417654 pub fn parse_index_type(&mut self) -> Result<IndexType, ParserError> {
7642- if self.parse_keyword(Keyword::BTREE) {
7643- Ok( IndexType::BTree)
7655+ Ok( if self.parse_keyword(Keyword::BTREE) {
7656+ IndexType::BTree
76447657 } else if self.parse_keyword(Keyword::HASH) {
7645- Ok(IndexType::Hash)
7646- } else {
7647- self.expected("index type {BTREE | HASH}", self.peek_token())
7648- }
7658+ IndexType::Hash
7659+ } else if self.parse_keyword(Keyword::GIN) {
7660+ IndexType::GIN
7661+ } else if self.parse_keyword(Keyword::GIST) {
7662+ IndexType::GiST
7663+ } else if self.parse_keyword(Keyword::SPGIST) {
7664+ IndexType::SPGiST
7665+ } else if self.parse_keyword(Keyword::BRIN) {
7666+ IndexType::BRIN
7667+ } else if self.parse_keyword(Keyword::BLOOM) {
7668+ IndexType::Bloom
7669+ } else {
7670+ IndexType::Custom(self.parse_identifier()?)
7671+ })
76497672 }
76507673
7651- /// Parse [USING {BTREE | HASH}]
7674+ /// Optionally parse the `USING` keyword, followed by an [IndexType]
7675+ /// Example:
7676+ /// ```sql
7677+ //// USING BTREE (name, age DESC)
7678+ /// ```
76527679 pub fn parse_optional_using_then_index_type(
76537680 &mut self,
76547681 ) -> Result<Option<IndexType>, ParserError> {
@@ -13641,10 +13668,42 @@ impl<'a> Parser<'a> {
1364113668 }
1364213669 }
1364313670
13644- /// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
13671+ /// Parse an [OrderByExpr] expression.
1364513672 pub fn parse_order_by_expr(&mut self) -> Result<OrderByExpr, ParserError> {
13673+ self.parse_order_by_expr_inner(false)
13674+ .map(|(order_by, _)| order_by)
13675+ }
13676+
13677+ /// Parse an [IndexColumn].
13678+ pub fn parse_create_index_expr(&mut self) -> Result<IndexColumn, ParserError> {
13679+ self.parse_order_by_expr_inner(true)
13680+ .map(|(column, operator_class)| IndexColumn {
13681+ column,
13682+ operator_class,
13683+ })
13684+ }
13685+
13686+ fn parse_order_by_expr_inner(
13687+ &mut self,
13688+ with_operator_class: bool,
13689+ ) -> Result<(OrderByExpr, Option<Ident>), ParserError> {
1364613690 let expr = self.parse_expr()?;
1364713691
13692+ let operator_class: Option<Ident> = if with_operator_class {
13693+ // We check that if non of the following keywords are present, then we parse an
13694+ // identifier as operator class.
13695+ if self
13696+ .peek_one_of_keywords(&[Keyword::ASC, Keyword::DESC, Keyword::NULLS, Keyword::WITH])
13697+ .is_some()
13698+ {
13699+ None
13700+ } else {
13701+ self.maybe_parse(|parser| parser.parse_identifier())?
13702+ }
13703+ } else {
13704+ None
13705+ };
13706+
1364813707 let options = self.parse_order_by_options()?;
1364913708
1365013709 let with_fill = if dialect_of!(self is ClickHouseDialect | GenericDialect)
@@ -13655,11 +13714,14 @@ impl<'a> Parser<'a> {
1365513714 None
1365613715 };
1365713716
13658- Ok(OrderByExpr {
13659- expr,
13660- options,
13661- with_fill,
13662- })
13717+ Ok((
13718+ OrderByExpr {
13719+ expr,
13720+ options,
13721+ with_fill,
13722+ },
13723+ operator_class,
13724+ ))
1366313725 }
1366413726
1366513727 fn parse_order_by_options(&mut self) -> Result<OrderByOptions, ParserError> {
0 commit comments