@@ -62,6 +62,9 @@ pub struct Query {
6262 /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/format)
6363 /// (ClickHouse-specific)
6464 pub format_clause : Option < FormatClause > ,
65+
66+ /// Pipe operator
67+ pub pipe_operators : Vec < PipeOperator > ,
6568}
6669
6770impl fmt:: Display for Query {
@@ -92,6 +95,9 @@ impl fmt::Display for Query {
9295 if let Some ( ref format) = self . format_clause {
9396 write ! ( f, " {}" , format) ?;
9497 }
98+ for pipe_operator in & self . pipe_operators {
99+ write ! ( f, " |> {}" , pipe_operator) ?;
100+ }
95101 Ok ( ( ) )
96102 }
97103}
@@ -1004,6 +1010,26 @@ impl fmt::Display for ExprWithAlias {
10041010 }
10051011}
10061012
1013+ /// An expression optionally followed by an alias and order by options.
1014+ ///
1015+ /// Example:
1016+ /// ```sql
1017+ /// 42 AS myint ASC
1018+ /// ```
1019+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1020+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1021+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1022+ pub struct ExprWithAliasAndOrderBy {
1023+ pub expr : ExprWithAlias ,
1024+ pub order_by : OrderByOptions ,
1025+ }
1026+
1027+ impl fmt:: Display for ExprWithAliasAndOrderBy {
1028+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1029+ write ! ( f, "{}{}" , self . expr, self . order_by)
1030+ }
1031+ }
1032+
10071033/// Arguments to a table-valued function
10081034#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
10091035#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -2513,6 +2539,135 @@ impl fmt::Display for OffsetRows {
25132539 }
25142540}
25152541
2542+ /// Pipe syntax, first introduced in Google BigQuery.
2543+ /// Example:
2544+ ///
2545+ /// ```sql
2546+ /// FROM Produce
2547+ /// |> WHERE sales > 0
2548+ /// |> AGGREGATE SUM(sales) AS total_sales, COUNT(*) AS num_sales
2549+ /// GROUP BY item;
2550+ /// ```
2551+ ///
2552+ /// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#pipe_syntax>
2553+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2554+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2555+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2556+ pub enum PipeOperator {
2557+ /// Limits the number of rows to return in a query, with an optional OFFSET clause to skip over rows.
2558+ ///
2559+ /// Syntax: `|> LIMIT <n> [OFFSET <m>]`
2560+ ///
2561+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#limit_pipe_operator>
2562+ Limit { expr : Expr , offset : Option < Expr > } ,
2563+ /// Filters the results of the input table.
2564+ ///
2565+ /// Syntax: `|> WHERE <condition>`
2566+ ///
2567+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#where_pipe_operator>
2568+ Where { expr : Expr } ,
2569+ /// `ORDER BY <expr> [ASC|DESC], ...`
2570+ OrderBy { exprs : Vec < OrderByExpr > } ,
2571+ /// Produces a new table with the listed columns, similar to the outermost SELECT clause in a table subquery in standard syntax.
2572+ ///
2573+ /// Syntax `|> SELECT <expr> [[AS] alias], ...`
2574+ ///
2575+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#select_pipe_operator>
2576+ Select { exprs : Vec < SelectItem > } ,
2577+ /// Propagates the existing table and adds computed columns, similar to SELECT *, new_column in standard syntax.
2578+ ///
2579+ /// Syntax: `|> EXTEND <expr> [[AS] alias], ...`
2580+ ///
2581+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#extend_pipe_operator>
2582+ Extend { exprs : Vec < SelectItem > } ,
2583+ /// Replaces the value of a column in the current table, similar to SELECT * REPLACE (expression AS column) in standard syntax.
2584+ ///
2585+ /// Syntax: `|> SET <column> = <expression>, ...`
2586+ ///
2587+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#set_pipe_operator>
2588+ Set { assignments : Vec < Assignment > } ,
2589+ /// Removes listed columns from the current table, similar to SELECT * EXCEPT (column) in standard syntax.
2590+ ///
2591+ /// Syntax: `|> DROP <column>, ...`
2592+ ///
2593+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#drop_pipe_operator>
2594+ Drop { columns : Vec < Ident > } ,
2595+ /// Introduces a table alias for the input table, similar to applying the AS alias clause on a table subquery in standard syntax.
2596+ ///
2597+ /// Syntax: `|> AS <alias>`
2598+ ///
2599+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#as_pipe_operator>
2600+ As { alias : Ident } ,
2601+ /// Performs aggregation on data across grouped rows or an entire table.
2602+ ///
2603+ /// Syntax: `|> AGGREGATE <agg_expr> [[AS] alias], ...`
2604+ ///
2605+ /// Syntax:
2606+ /// ```norust
2607+ /// |> AGGREGATE [<agg_expr> [[AS] alias], ...]
2608+ /// GROUP BY <grouping_expr> [AS alias], ...
2609+ /// ```
2610+ ///
2611+ /// See more at <https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#aggregate_pipe_operator>
2612+ Aggregate {
2613+ full_table_exprs : Vec < ExprWithAliasAndOrderBy > ,
2614+ group_by_expr : Vec < ExprWithAliasAndOrderBy > ,
2615+ } ,
2616+ }
2617+
2618+ impl fmt:: Display for PipeOperator {
2619+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2620+ match self {
2621+ PipeOperator :: Select { exprs } => {
2622+ write ! ( f, "SELECT {}" , display_comma_separated( exprs. as_slice( ) ) )
2623+ }
2624+ PipeOperator :: Extend { exprs } => {
2625+ write ! ( f, "EXTEND {}" , display_comma_separated( exprs. as_slice( ) ) )
2626+ }
2627+ PipeOperator :: Set { assignments } => {
2628+ write ! ( f, "SET {}" , display_comma_separated( assignments. as_slice( ) ) )
2629+ }
2630+ PipeOperator :: Drop { columns } => {
2631+ write ! ( f, "DROP {}" , display_comma_separated( columns. as_slice( ) ) )
2632+ }
2633+ PipeOperator :: As { alias } => {
2634+ write ! ( f, "AS {}" , alias)
2635+ }
2636+ PipeOperator :: Limit { expr, offset } => {
2637+ write ! ( f, "LIMIT {}" , expr) ?;
2638+ if let Some ( offset) = offset {
2639+ write ! ( f, " OFFSET {}" , offset) ?;
2640+ }
2641+ Ok ( ( ) )
2642+ }
2643+ PipeOperator :: Aggregate {
2644+ full_table_exprs,
2645+ group_by_expr,
2646+ } => {
2647+ write ! ( f, "AGGREGATE" ) ?;
2648+ if !full_table_exprs. is_empty ( ) {
2649+ write ! (
2650+ f,
2651+ " {}" ,
2652+ display_comma_separated( full_table_exprs. as_slice( ) )
2653+ ) ?;
2654+ }
2655+ if !group_by_expr. is_empty ( ) {
2656+ write ! ( f, " GROUP BY {}" , display_comma_separated( group_by_expr) ) ?;
2657+ }
2658+ Ok ( ( ) )
2659+ }
2660+
2661+ PipeOperator :: Where { expr } => {
2662+ write ! ( f, "WHERE {}" , expr)
2663+ }
2664+ PipeOperator :: OrderBy { exprs } => {
2665+ write ! ( f, "ORDER BY {}" , display_comma_separated( exprs. as_slice( ) ) )
2666+ }
2667+ }
2668+ }
2669+ }
2670+
25162671#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
25172672#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
25182673#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
0 commit comments