@@ -32,7 +32,7 @@ pub struct Query {
32
32
/// SELECT or UNION / EXCEPT / INTERSECT
33
33
pub body : Box < SetExpr > ,
34
34
/// ORDER BY
35
- pub order_by : Vec < OrderByExpr > ,
35
+ pub order_by : Option < OrderBy > ,
36
36
/// `LIMIT { <N> | ALL }`
37
37
pub limit : Option < Expr > ,
38
38
@@ -53,8 +53,17 @@ impl fmt::Display for Query {
53
53
write ! ( f, "{with} " ) ?;
54
54
}
55
55
write ! ( f, "{}" , self . body) ?;
56
- if !self . order_by . is_empty ( ) {
57
- write ! ( f, " ORDER BY {}" , display_comma_separated( & self . order_by) ) ?;
56
+ if let Some ( ref order_by) = self . order_by {
57
+ write ! ( f, " ORDER BY" ) ?;
58
+ if !order_by. exprs . is_empty ( ) {
59
+ write ! ( f, " {}" , display_comma_separated( & order_by. exprs) ) ?;
60
+ }
61
+ if let Some ( ref interpolate) = order_by. interpolate {
62
+ match & interpolate. exprs {
63
+ Some ( exprs) => write ! ( f, " INTERPOLATE ({})" , display_comma_separated( exprs) ) ?,
64
+ None => write ! ( f, " INTERPOLATE" ) ?,
65
+ }
66
+ }
58
67
}
59
68
if let Some ( ref limit) = self . limit {
60
69
write ! ( f, " LIMIT {limit}" ) ?;
@@ -100,6 +109,17 @@ pub enum SetExpr {
100
109
Table ( Box < Table > ) ,
101
110
}
102
111
112
+ impl SetExpr {
113
+ /// If this `SetExpr` is a `SELECT`, returns the [`Select`].
114
+ pub fn as_select ( & self ) -> Option < & Select > {
115
+ if let Self :: Select ( select) = self {
116
+ Some ( & * * select)
117
+ } else {
118
+ None
119
+ }
120
+ }
121
+ }
122
+
103
123
impl fmt:: Display for SetExpr {
104
124
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
105
125
match self {
@@ -1223,6 +1243,18 @@ pub enum JoinConstraint {
1223
1243
None ,
1224
1244
}
1225
1245
1246
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1247
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1248
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1249
+ pub struct OrderBy {
1250
+ pub exprs : Vec < OrderByExpr > ,
1251
+ /// Optional: `INTERPOLATE`
1252
+ /// Supported by [ClickHouse syntax]
1253
+ ///
1254
+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1255
+ pub interpolate : Option < Interpolate > ,
1256
+ }
1257
+
1226
1258
/// An `ORDER BY` expression
1227
1259
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1228
1260
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -1233,6 +1265,9 @@ pub struct OrderByExpr {
1233
1265
pub asc : Option < bool > ,
1234
1266
/// Optional `NULLS FIRST` or `NULLS LAST`
1235
1267
pub nulls_first : Option < bool > ,
1268
+ /// Optional: `WITH FILL`
1269
+ /// Supported by [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1270
+ pub with_fill : Option < WithFill > ,
1236
1271
}
1237
1272
1238
1273
impl fmt:: Display for OrderByExpr {
@@ -1248,6 +1283,67 @@ impl fmt::Display for OrderByExpr {
1248
1283
Some ( false ) => write ! ( f, " NULLS LAST" ) ?,
1249
1284
None => ( ) ,
1250
1285
}
1286
+ if let Some ( ref with_fill) = self . with_fill {
1287
+ write ! ( f, " {}" , with_fill) ?
1288
+ }
1289
+ Ok ( ( ) )
1290
+ }
1291
+ }
1292
+
1293
+ /// ClickHouse `WITH FILL` modifier for `ORDER BY` clause.
1294
+ /// Supported by [ClickHouse syntax]
1295
+ ///
1296
+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1297
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1298
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1299
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1300
+ pub struct WithFill {
1301
+ pub from : Option < Expr > ,
1302
+ pub to : Option < Expr > ,
1303
+ pub step : Option < Expr > ,
1304
+ }
1305
+
1306
+ impl fmt:: Display for WithFill {
1307
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1308
+ write ! ( f, "WITH FILL" ) ?;
1309
+ if let Some ( ref from) = self . from {
1310
+ write ! ( f, " FROM {}" , from) ?;
1311
+ }
1312
+ if let Some ( ref to) = self . to {
1313
+ write ! ( f, " TO {}" , to) ?;
1314
+ }
1315
+ if let Some ( ref step) = self . step {
1316
+ write ! ( f, " STEP {}" , step) ?;
1317
+ }
1318
+ Ok ( ( ) )
1319
+ }
1320
+ }
1321
+
1322
+ /// ClickHouse `INTERPOLATE` clause for use in `ORDER BY` clause when using `WITH FILL` modifier.
1323
+ /// Supported by [ClickHouse syntax]
1324
+ ///
1325
+ /// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
1326
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1327
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1328
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1329
+ pub struct InterpolateExpr {
1330
+ pub column : WithSpan < Ident > ,
1331
+ pub expr : Option < Expr > ,
1332
+ }
1333
+
1334
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1335
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1336
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1337
+ pub struct Interpolate {
1338
+ pub exprs : Option < Vec < InterpolateExpr > > ,
1339
+ }
1340
+
1341
+ impl fmt:: Display for InterpolateExpr {
1342
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1343
+ write ! ( f, "{}" , self . column) ?;
1344
+ if let Some ( ref expr) = self . expr {
1345
+ write ! ( f, " AS {}" , expr) ?;
1346
+ }
1251
1347
Ok ( ( ) )
1252
1348
}
1253
1349
}
0 commit comments