@@ -16597,6 +16597,12 @@ impl<'a> Parser<'a> {
1659716597 // `(mytable AS alias)`
1659816598 alias.replace(outer_alias);
1659916599 }
16600+ TableFactor::UnpivotExpr { .. } => {
16601+ return Err(ParserError::ParserError(
16602+ "alias after parenthesized UNPIVOT expression is not supported"
16603+ .to_string(),
16604+ ))
16605+ }
1660016606 };
1660116607 }
1660216608 // Do not store the extra set of parens in the AST
@@ -16678,6 +16684,8 @@ impl<'a> Parser<'a> {
1667816684 with_offset_alias,
1667916685 with_ordinality,
1668016686 })
16687+ } else if self.dialect.supports_unpivot_expr() && self.peek_keyword(Keyword::UNPIVOT) {
16688+ self.parse_unpivot_expr_table_factor()
1668116689 } else if self.parse_keyword_with_tokens(Keyword::JSON_TABLE, &[Token::LParen]) {
1668216690 let json_expr = self.parse_expr()?;
1668316691 self.expect_token(&Token::Comma)?;
@@ -17676,6 +17684,28 @@ impl<'a> Parser<'a> {
1767617684 })
1767717685 }
1767817686
17687+ /// Parse an object UNPIVOT table factor in FROM clause.
17688+ ///
17689+ /// Syntax:
17690+ /// `UNPIVOT expression AS value_alias [AT attribute_alias]`
17691+ pub fn parse_unpivot_expr_table_factor(&mut self) -> Result<TableFactor, ParserError> {
17692+ self.expect_keyword_is(Keyword::UNPIVOT)?;
17693+ let expression = self.parse_expr()?;
17694+ self.expect_keyword_is(Keyword::AS)?;
17695+ let value_alias = self.parse_identifier()?;
17696+ let attribute_alias = if self.parse_keyword(Keyword::AT) {
17697+ Some(self.parse_identifier()?)
17698+ } else {
17699+ None
17700+ };
17701+
17702+ Ok(TableFactor::UnpivotExpr {
17703+ expression,
17704+ value_alias,
17705+ attribute_alias,
17706+ })
17707+ }
17708+
1767917709 /// Parse a JOIN constraint (`NATURAL`, `ON <expr>`, `USING (...)`, or no constraint).
1768017710 pub fn parse_join_constraint(&mut self, natural: bool) -> Result<JoinConstraint, ParserError> {
1768117711 if natural {
0 commit comments