@@ -3955,6 +3955,18 @@ impl<'a> Parser<'a> {
39553955 true
39563956 }
39573957
3958+ /// If the current token is one of the given `keywords`, returns the keyword
3959+ /// that matches, without consuming the token. Otherwise, returns [`None`].
3960+ #[must_use]
3961+ pub fn peek_one_of_keywords(&self, keywords: &[Keyword]) -> Option<Keyword> {
3962+ for keyword in keywords {
3963+ if self.peek_keyword(*keyword) {
3964+ return Some(*keyword);
3965+ }
3966+ }
3967+ None
3968+ }
3969+
39583970 /// If the current token is one of the given `keywords`, consume the token
39593971 /// and return the keyword that matches. Otherwise, no tokens are consumed
39603972 /// and returns [`None`].
@@ -6406,12 +6418,13 @@ impl<'a> Parser<'a> {
64066418 };
64076419 let table_name = self.parse_object_name(false)?;
64086420 let using = if self.parse_keyword(Keyword::USING) {
6409- Some(self.parse_identifier ()?)
6421+ Some(self.parse_index_type ()?)
64106422 } else {
64116423 None
64126424 };
6425+
64136426 self.expect_token(&Token::LParen)?;
6414- let columns = self.parse_comma_separated(Parser::parse_order_by_expr )?;
6427+ let columns = self.parse_comma_separated(Parser::parse_create_index_expr )?;
64156428 self.expect_token(&Token::RParen)?;
64166429
64176430 let include = if self.parse_keyword(Keyword::INCLUDE) {
@@ -7629,16 +7642,30 @@ impl<'a> Parser<'a> {
76297642 }
76307643
76317644 pub fn parse_index_type(&mut self) -> Result<IndexType, ParserError> {
7632- if self.parse_keyword(Keyword::BTREE) {
7633- Ok( IndexType::BTree)
7645+ Ok( if self.parse_keyword(Keyword::BTREE) {
7646+ IndexType::BTree
76347647 } else if self.parse_keyword(Keyword::HASH) {
7635- Ok(IndexType::Hash)
7636- } else {
7637- self.expected("index type {BTREE | HASH}", self.peek_token())
7638- }
7648+ IndexType::Hash
7649+ } else if self.parse_keyword(Keyword::GIN) {
7650+ IndexType::GIN
7651+ } else if self.parse_keyword(Keyword::GIST) {
7652+ IndexType::GiST
7653+ } else if self.parse_keyword(Keyword::SPGIST) {
7654+ IndexType::SPGiST
7655+ } else if self.parse_keyword(Keyword::BRIN) {
7656+ IndexType::BRIN
7657+ } else if self.parse_keyword(Keyword::BLOOM) {
7658+ IndexType::Bloom
7659+ } else {
7660+ IndexType::Custom(self.parse_identifier()?)
7661+ })
76397662 }
76407663
7641- /// Parse [USING {BTREE | HASH}]
7664+ /// Optionally parse the `USING` keyword, followed by an [IndexType]
7665+ /// Example:
7666+ /// ```sql
7667+ //// USING BTREE (name, age DESC)
7668+ /// ```
76427669 pub fn parse_optional_using_then_index_type(
76437670 &mut self,
76447671 ) -> Result<Option<IndexType>, ParserError> {
@@ -13631,10 +13658,42 @@ impl<'a> Parser<'a> {
1363113658 }
1363213659 }
1363313660
13634- /// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
13661+ /// Parse an [OrderByExpr] expression.
1363513662 pub fn parse_order_by_expr(&mut self) -> Result<OrderByExpr, ParserError> {
13663+ self.parse_order_by_expr_inner(false)
13664+ .map(|(order_by, _)| order_by)
13665+ }
13666+
13667+ /// Parse an [IndexColumn].
13668+ pub fn parse_create_index_expr(&mut self) -> Result<IndexColumn, ParserError> {
13669+ self.parse_order_by_expr_inner(true)
13670+ .map(|(column, operator_class)| IndexColumn {
13671+ column,
13672+ operator_class,
13673+ })
13674+ }
13675+
13676+ fn parse_order_by_expr_inner(
13677+ &mut self,
13678+ with_operator_class: bool,
13679+ ) -> Result<(OrderByExpr, Option<Ident>), ParserError> {
1363613680 let expr = self.parse_expr()?;
1363713681
13682+ let operator_class: Option<Ident> = if with_operator_class {
13683+ // We check that if non of the following keywords are present, then we parse an
13684+ // identifier as operator class.
13685+ if self
13686+ .peek_one_of_keywords(&[Keyword::ASC, Keyword::DESC, Keyword::NULLS, Keyword::WITH])
13687+ .is_some()
13688+ {
13689+ None
13690+ } else {
13691+ self.maybe_parse(|parser| parser.parse_identifier())?
13692+ }
13693+ } else {
13694+ None
13695+ };
13696+
1363813697 let options = self.parse_order_by_options()?;
1363913698
1364013699 let with_fill = if dialect_of!(self is ClickHouseDialect | GenericDialect)
@@ -13645,11 +13704,14 @@ impl<'a> Parser<'a> {
1364513704 None
1364613705 };
1364713706
13648- Ok(OrderByExpr {
13649- expr,
13650- options,
13651- with_fill,
13652- })
13707+ Ok((
13708+ OrderByExpr {
13709+ expr,
13710+ options,
13711+ with_fill,
13712+ },
13713+ operator_class,
13714+ ))
1365313715 }
1365413716
1365513717 fn parse_order_by_options(&mut self) -> Result<OrderByOptions, ParserError> {
0 commit comments