@@ -957,7 +957,8 @@ pub enum TableFactor {
957957 table : Box < TableFactor > ,
958958 aggregate_functions : Vec < ExprWithAlias > , // Function expression
959959 value_column : Vec < Ident > ,
960- pivot_values : Vec < ExprWithAlias > ,
960+ value_source : PivotValueSource ,
961+ default_on_null : Option < Expr > ,
961962 alias : Option < TableAlias > ,
962963 } ,
963964 /// An UNPIVOT operation on a table.
@@ -998,6 +999,41 @@ pub enum TableFactor {
998999 } ,
9991000}
10001001
1002+ /// The source of values in a `PIVOT` operation.
1003+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1004+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1005+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1006+ pub enum PivotValueSource {
1007+ /// Pivot on a static list of values.
1008+ ///
1009+ /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-a-specified-list-of-column-values-for-the-pivot-column>.
1010+ List ( Vec < ExprWithAlias > ) ,
1011+ /// Pivot on all distinct values of the pivot column.
1012+ ///
1013+ /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-all-distinct-column-values-automatically-with-dynamic-pivot>.
1014+ Any ( Vec < OrderByExpr > ) ,
1015+ /// Pivot on all values returned by a subquery.
1016+ ///
1017+ /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-column-values-using-a-subquery-with-dynamic-pivot>.
1018+ Subquery ( Query ) ,
1019+ }
1020+
1021+ impl fmt:: Display for PivotValueSource {
1022+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1023+ match self {
1024+ PivotValueSource :: List ( values) => write ! ( f, "{}" , display_comma_separated( values) ) ,
1025+ PivotValueSource :: Any ( order_by) => {
1026+ write ! ( f, "ANY" ) ?;
1027+ if !order_by. is_empty ( ) {
1028+ write ! ( f, " ORDER BY {}" , display_comma_separated( order_by) ) ?;
1029+ }
1030+ Ok ( ( ) )
1031+ }
1032+ PivotValueSource :: Subquery ( query) => write ! ( f, "{query}" ) ,
1033+ }
1034+ }
1035+ }
1036+
10011037/// An item in the `MEASURES` subclause of a `MATCH_RECOGNIZE` operation.
10021038///
10031039/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#measures-specifying-additional-output-columns>.
@@ -1324,17 +1360,20 @@ impl fmt::Display for TableFactor {
13241360 table,
13251361 aggregate_functions,
13261362 value_column,
1327- pivot_values,
1363+ value_source,
1364+ default_on_null,
13281365 alias,
13291366 } => {
13301367 write ! (
13311368 f,
1332- "{} PIVOT({} FOR {} IN ({}))" ,
1333- table,
1369+ "{table} PIVOT({} FOR {} IN ({value_source})" ,
13341370 display_comma_separated( aggregate_functions) ,
13351371 Expr :: CompoundIdentifier ( value_column. to_vec( ) ) ,
1336- display_comma_separated( pivot_values)
13371372 ) ?;
1373+ if let Some ( expr) = default_on_null {
1374+ write ! ( f, " DEFAULT ON NULL ({expr})" ) ?;
1375+ }
1376+ write ! ( f, ")" ) ?;
13381377 if alias. is_some ( ) {
13391378 write ! ( f, " AS {}" , alias. as_ref( ) . unwrap( ) ) ?;
13401379 }
0 commit comments