@@ -145,6 +145,26 @@ pub enum SelectTarget {
145145 } ,
146146}
147147
148+ impl SelectTarget {
149+ pub fn is_star ( & self ) -> bool {
150+ match self {
151+ SelectTarget :: AliasedExpr { .. } => false ,
152+ SelectTarget :: QualifiedName { qualified, .. } => {
153+ matches ! ( qualified. last( ) , Some ( Indirection :: Star ( _) ) )
154+ }
155+ }
156+ }
157+
158+ pub fn exclude ( & mut self , exclude : Vec < Identifier > ) {
159+ match self {
160+ SelectTarget :: AliasedExpr { .. } => unreachable ! ( ) ,
161+ SelectTarget :: QualifiedName { exclude : e, .. } => {
162+ * e = Some ( exclude) ;
163+ }
164+ }
165+ }
166+ }
167+
148168pub type QualifiedName = Vec < Indirection > ;
149169
150170/// Indirection of a select result, like a part of `db.table.column`.
@@ -164,6 +184,20 @@ pub enum TimeTravelPoint {
164184 Timestamp ( Box < Expr > ) ,
165185}
166186
187+ #[ derive( Debug , Clone , PartialEq ) ]
188+ pub struct Pivot {
189+ pub aggregate : Expr ,
190+ pub value_column : Identifier ,
191+ pub values : Vec < Expr > ,
192+ }
193+
194+ #[ derive( Debug , Clone , PartialEq ) ]
195+ pub struct Unpivot {
196+ pub value_column : Identifier ,
197+ pub column_name : Identifier ,
198+ pub names : Vec < Identifier > ,
199+ }
200+
167201/// A table name or a parenthesized subquery with an optional alias
168202#[ derive( Debug , Clone , PartialEq ) ]
169203pub enum TableReference {
@@ -175,6 +209,8 @@ pub enum TableReference {
175209 table : Identifier ,
176210 alias : Option < TableAlias > ,
177211 travel_point : Option < TimeTravelPoint > ,
212+ pivot : Option < Box < Pivot > > ,
213+ unpivot : Option < Box < Unpivot > > ,
178214 } ,
179215 // `TABLE(expr)[ AS alias ]`
180216 TableFunction {
@@ -202,6 +238,22 @@ pub enum TableReference {
202238 } ,
203239}
204240
241+ impl TableReference {
242+ pub fn pivot ( & self ) -> Option < & Pivot > {
243+ match self {
244+ TableReference :: Table { pivot, .. } => pivot. as_ref ( ) . map ( |b| b. as_ref ( ) ) ,
245+ _ => None ,
246+ }
247+ }
248+
249+ pub fn unpivot ( & self ) -> Option < & Unpivot > {
250+ match self {
251+ TableReference :: Table { unpivot, .. } => unpivot. as_ref ( ) . map ( |b| b. as_ref ( ) ) ,
252+ _ => None ,
253+ }
254+ }
255+ }
256+
205257#[ derive( Debug , Clone , PartialEq , Eq ) ]
206258pub struct TableAlias {
207259 pub name : Identifier ,
@@ -282,6 +334,28 @@ impl Display for TableAlias {
282334 }
283335}
284336
337+ impl Display for Pivot {
338+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
339+ write ! ( f, "PIVOT({} FOR {} IN (" , self . aggregate, self . value_column) ?;
340+ write_comma_separated_list ( f, & self . values ) ?;
341+ write ! ( f, "))" ) ?;
342+ Ok ( ( ) )
343+ }
344+ }
345+
346+ impl Display for Unpivot {
347+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
348+ write ! (
349+ f,
350+ "UNPIVOT({} FOR {} IN (" ,
351+ self . value_column, self . column_name
352+ ) ?;
353+ write_comma_separated_list ( f, & self . names ) ?;
354+ write ! ( f, "))" ) ?;
355+ Ok ( ( ) )
356+ }
357+ }
358+
285359impl Display for TableReference {
286360 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
287361 match self {
@@ -292,6 +366,8 @@ impl Display for TableReference {
292366 table,
293367 alias,
294368 travel_point,
369+ pivot,
370+ unpivot,
295371 } => {
296372 write_period_separated_list (
297373 f,
@@ -309,6 +385,13 @@ impl Display for TableReference {
309385 if let Some ( alias) = alias {
310386 write ! ( f, " AS {alias}" ) ?;
311387 }
388+ if let Some ( pivot) = pivot {
389+ write ! ( f, " {pivot}" ) ?;
390+ }
391+
392+ if let Some ( unpivot) = unpivot {
393+ write ! ( f, " {unpivot}" ) ?;
394+ }
312395 }
313396 TableReference :: TableFunction {
314397 span : _,
@@ -545,6 +628,7 @@ impl Display for CTE {
545628 Ok ( ( ) )
546629 }
547630}
631+
548632impl Display for With {
549633 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
550634 if self . recursive {
0 commit comments