Skip to content

Commit 41c45cd

Browse files
nickprestaalamb
authored andcommitted
[ClickHouse] Add support for WITH FILL to OrderByExpr (apache#1330)
Co-authored-by: Andrew Lamb <[email protected]>
1 parent e0d3f76 commit 41c45cd

File tree

9 files changed

+614
-51
lines changed

9 files changed

+614
-51
lines changed

src/ast/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ pub use self::ddl::{
4141
pub use self::operator::{BinaryOperator, UnaryOperator};
4242
pub use self::query::{
4343
AggregateItem, Cte, Distinct, ExceptSelectItem, ExcludeSelectItem, Fetch, GroupByExpr,
44-
IdentWithAlias, Join, JoinConstraint, JoinOperator, LateralView, LockClause, LockType,
45-
NamedWindowDefinition, NonBlock, Offset, OffsetRows, OrderByExpr, Query, RenameSelectItem,
46-
ReplaceSelectElement, ReplaceSelectItem, SamplingMethod, Select, SelectInto, SelectItem,
47-
SelectionCount, SetExpr, SetOperator, SetQuantifier, Table, TableAlias, TableFactor,
48-
TableSampleSeed, TableVersion, TableWithJoins, Top, ValueTableMode, Values,
49-
WildcardAdditionalOptions, With,
44+
IdentWithAlias, Interpolate, InterpolateExpr, Join, JoinConstraint, JoinOperator, LateralView,
45+
LockClause, LockType, NamedWindowDefinition, NonBlock, Offset, OffsetRows, OrderBy,
46+
OrderByExpr, Query, RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, SamplingMethod,
47+
Select, SelectInto, SelectItem, SelectionCount, SetExpr, SetOperator, SetQuantifier, Table,
48+
TableAlias, TableFactor, TableSampleSeed, TableVersion, TableWithJoins, Top, ValueTableMode,
49+
Values, WildcardAdditionalOptions, With, WithFill,
5050
};
5151
pub use self::value::{
5252
escape_quoted_string, DateTimeField, DollarQuotedString, ObjectConstantKeyValue,

src/ast/query.rs

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub struct Query {
3232
/// SELECT or UNION / EXCEPT / INTERSECT
3333
pub body: Box<SetExpr>,
3434
/// ORDER BY
35-
pub order_by: Vec<OrderByExpr>,
35+
pub order_by: Option<OrderBy>,
3636
/// `LIMIT { <N> | ALL }`
3737
pub limit: Option<Expr>,
3838

@@ -53,8 +53,17 @@ impl fmt::Display for Query {
5353
write!(f, "{with} ")?;
5454
}
5555
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+
}
5867
}
5968
if let Some(ref limit) = self.limit {
6069
write!(f, " LIMIT {limit}")?;
@@ -100,6 +109,17 @@ pub enum SetExpr {
100109
Table(Box<Table>),
101110
}
102111

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+
103123
impl fmt::Display for SetExpr {
104124
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105125
match self {
@@ -1223,6 +1243,18 @@ pub enum JoinConstraint {
12231243
None,
12241244
}
12251245

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+
12261258
/// An `ORDER BY` expression
12271259
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
12281260
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -1233,6 +1265,9 @@ pub struct OrderByExpr {
12331265
pub asc: Option<bool>,
12341266
/// Optional `NULLS FIRST` or `NULLS LAST`
12351267
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>,
12361271
}
12371272

12381273
impl fmt::Display for OrderByExpr {
@@ -1248,6 +1283,67 @@ impl fmt::Display for OrderByExpr {
12481283
Some(false) => write!(f, " NULLS LAST")?,
12491284
None => (),
12501285
}
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+
}
12511347
Ok(())
12521348
}
12531349
}

src/keywords.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ define_keywords!(
284284
FILE,
285285
FILES,
286286
FILE_FORMAT,
287+
FILL,
287288
FILTER,
288289
FINAL,
289290
FIRST,
@@ -358,6 +359,7 @@ define_keywords!(
358359
INT64,
359360
INT8,
360361
INTEGER,
362+
INTERPOLATE,
361363
INTERSECT,
362364
INTERSECTION,
363365
INTERVAL,
@@ -620,6 +622,7 @@ define_keywords!(
620622
STDDEV_SAMP,
621623
STDIN,
622624
STDOUT,
625+
STEP,
623626
STORAGE_INTEGRATION,
624627
STORED,
625628
STRICT,

0 commit comments

Comments
 (0)