diff --git a/src/parser/mod.rs b/src/parser/mod.rs index eb4ef68a6..28c47b639 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -6589,9 +6589,20 @@ impl<'a> Parser<'a> { // `parse_derived_table_factor` below will return success after parsing the // subquery, followed by the closing ')', and the alias of the derived table. // In the example above this is case (3). - return_ok_if_some!( + if let Some(mut table) = self.maybe_parse(|parser| parser.parse_derived_table_factor(NotLateral)) - ); + { + while let Some(kw) = self.parse_one_of_keywords(&[Keyword::PIVOT, Keyword::UNPIVOT]) + { + table = match kw { + Keyword::PIVOT => self.parse_pivot_table_factor(table)?, + Keyword::UNPIVOT => self.parse_unpivot_table_factor(table)?, + _ => unreachable!(), + } + } + return Ok(table); + } + // A parsing error from `parse_derived_table_factor` indicates that the '(' we've // recently consumed does not start a derived table (cases 1, 2, or 4). // `maybe_parse` will ignore such an error and rewind to be after the opening '('. diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index f0a077973..9c4b2ddeb 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -1134,3 +1134,10 @@ fn parse_division_correctly() { "SELECT tbl1.field / tbl2.field FROM tbl1 JOIN tbl2 ON tbl1.id = tbl2.entity_id", ); } + +#[test] +fn parse_pivot_of_table_factor_derived() { + snowflake().verified_stmt( + "SELECT * FROM (SELECT place_id, weekday, open FROM times AS p) PIVOT(max(open) FOR weekday IN (0, 1, 2, 3, 4, 5, 6)) AS p (place_id, open_sun, open_mon, open_tue, open_wed, open_thu, open_fri, open_sat)" + ); +}