diff --git a/src/ast/query.rs b/src/ast/query.rs index 857009dde..a6c34bfae 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -319,6 +319,14 @@ pub enum TableFactor { /// https://docs.snowflake.com/en/sql-reference/constructs/pivot.html Pivot { expr: Expr, + alias: Option, + val: Ident, + pivot_vals: Vec, + }, + /// https://docs.snowflake.com/en/sql-reference/constructs/unpivot.html + Unpivot { + expr: Expr, + alias: Option, val: Ident, pivot_vals: Vec, }, @@ -389,6 +397,25 @@ impl fmt::Display for TableFactor { } TableFactor::Pivot { expr, + alias, + val, + pivot_vals, + } => { + write!(f, "({} FOR {} IN (", expr, val)?; + let mut delim = ""; + for pivot_val in pivot_vals { + write!(f, "{}{}", delim, pivot_val)?; + delim = ", "; + } + write!(f, "))")?; + if let Some(alias) = alias { + write!(f, " AS {}", alias)?; + } + Ok(()) + } + TableFactor::Unpivot { + expr, + alias, val, pivot_vals, } => { @@ -398,7 +425,11 @@ impl fmt::Display for TableFactor { write!(f, "{}{}", delim, pivot_val)?; delim = ", "; } - write!(f, "))") + write!(f, "))")?; + if let Some(alias) = alias { + write!(f, " AS {}", alias)?; + } + Ok(()) } TableFactor::NestedJoin(table_reference) => write!(f, "({})", table_reference), } diff --git a/src/parser.rs b/src/parser.rs index 005a88cb8..0b7764b70 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2631,6 +2631,7 @@ impl<'a> Parser<'a> { alias.replace(outer_alias); } TableFactor::Pivot { .. } => unreachable!(), + TableFactor::Unpivot { .. } => unreachable!(), TableFactor::NestedJoin(_) => unreachable!(), }; } @@ -2681,8 +2682,10 @@ impl<'a> Parser<'a> { let pivot_vals = self.parse_comma_separated(Parser::parse_expr)?; self.expect_token(&Token::RParen)?; self.expect_token(&Token::RParen)?; + let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?; Ok(TableFactor::Pivot { expr, + alias, val, pivot_vals, })