@@ -33,7 +33,7 @@ pub struct Query {
3333 /// SELECT or UNION / EXCEPT / INTERSECT
3434 pub body : Box < SetExpr > ,
3535 /// ORDER BY
36- pub order_by : Vec < OrderByExpr > ,
36+ pub order_by : Option < OrderBy > ,
3737 /// `LIMIT { <N> | ALL }`
3838 pub limit : Option < Expr > ,
3939
@@ -67,8 +67,17 @@ impl fmt::Display for Query {
6767 write ! ( f, "{with} " ) ?;
6868 }
6969 write ! ( f, "{}" , self . body) ?;
70- if !self . order_by . is_empty ( ) {
71- write ! ( f, " ORDER BY {}" , display_comma_separated( & self . order_by) ) ?;
70+ if let Some ( ref order_by) = self . order_by {
71+ write ! ( f, " ORDER BY" ) ?;
72+ if !order_by. exprs . is_empty ( ) {
73+ write ! ( f, " {}" , display_comma_separated( & order_by. exprs) ) ?;
74+ }
75+ if let Some ( ref interpolate) = order_by. interpolate {
76+ match & interpolate. exprs {
77+ Some ( exprs) => write ! ( f, " INTERPOLATE ({})" , display_comma_separated( exprs) ) ?,
78+ None => write ! ( f, " INTERPOLATE" ) ?,
79+ }
80+ }
7281 }
7382 if let Some ( ref limit) = self . limit {
7483 write ! ( f, " LIMIT {limit}" ) ?;
@@ -1668,6 +1677,18 @@ pub enum JoinConstraint {
16681677 None ,
16691678}
16701679
1680+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1681+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1682+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1683+ pub struct OrderBy {
1684+ pub exprs : Vec < OrderByExpr > ,
1685+ /// Optional: `INTERPOLATE`
1686+ /// Supported by [ClickHouse syntax]
1687+ ///
1688+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1689+ pub interpolate : Option < Interpolate > ,
1690+ }
1691+
16711692/// An `ORDER BY` expression
16721693#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
16731694#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -1678,6 +1699,9 @@ pub struct OrderByExpr {
16781699 pub asc : Option < bool > ,
16791700 /// Optional `NULLS FIRST` or `NULLS LAST`
16801701 pub nulls_first : Option < bool > ,
1702+ /// Optional: `WITH FILL`
1703+ /// Supported by [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1704+ pub with_fill : Option < WithFill > ,
16811705}
16821706
16831707impl fmt:: Display for OrderByExpr {
@@ -1693,6 +1717,67 @@ impl fmt::Display for OrderByExpr {
16931717 Some ( false ) => write ! ( f, " NULLS LAST" ) ?,
16941718 None => ( ) ,
16951719 }
1720+ if let Some ( ref with_fill) = self . with_fill {
1721+ write ! ( f, " {}" , with_fill) ?
1722+ }
1723+ Ok ( ( ) )
1724+ }
1725+ }
1726+
1727+ /// ClickHouse `WITH FILL` modifier for `ORDER BY` clause.
1728+ /// Supported by [ClickHouse syntax]
1729+ ///
1730+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1731+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1732+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1733+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1734+ pub struct WithFill {
1735+ pub from : Option < Expr > ,
1736+ pub to : Option < Expr > ,
1737+ pub step : Option < Expr > ,
1738+ }
1739+
1740+ impl fmt:: Display for WithFill {
1741+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1742+ write ! ( f, "WITH FILL" ) ?;
1743+ if let Some ( ref from) = self . from {
1744+ write ! ( f, " FROM {}" , from) ?;
1745+ }
1746+ if let Some ( ref to) = self . to {
1747+ write ! ( f, " TO {}" , to) ?;
1748+ }
1749+ if let Some ( ref step) = self . step {
1750+ write ! ( f, " STEP {}" , step) ?;
1751+ }
1752+ Ok ( ( ) )
1753+ }
1754+ }
1755+
1756+ /// ClickHouse `INTERPOLATE` clause for use in `ORDER BY` clause when using `WITH FILL` modifier.
1757+ /// Supported by [ClickHouse syntax]
1758+ ///
1759+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1760+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1761+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1762+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1763+ pub struct InterpolateExpr {
1764+ pub column : Ident ,
1765+ pub expr : Option < Expr > ,
1766+ }
1767+
1768+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1769+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1770+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1771+ pub struct Interpolate {
1772+ pub exprs : Option < Vec < InterpolateExpr > > ,
1773+ }
1774+
1775+ impl fmt:: Display for InterpolateExpr {
1776+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1777+ write ! ( f, "{}" , self . column) ?;
1778+ if let Some ( ref expr) = self . expr {
1779+ write ! ( f, " AS {}" , expr) ?;
1780+ }
16961781 Ok ( ( ) )
16971782 }
16981783}
0 commit comments