Skip to content

Commit d396e68

Browse files
committed
feat: order by all
1 parent 46cfcfe commit d396e68

File tree

6 files changed

+251
-59
lines changed

6 files changed

+251
-59
lines changed

src/ast/mod.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,16 @@ pub use self::query::{
6666
JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn, JsonTableNestedColumn,
6767
LateralView, LockClause, LockType, MatchRecognizePattern, MatchRecognizeSymbol, Measure,
6868
NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset, OffsetRows, OpenJsonTableColumn,
69-
OrderBy, OrderByExpr, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
70-
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
71-
SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator,
72-
SetQuantifier, Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
73-
TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
74-
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
75-
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
76-
TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
77-
ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
69+
OrderBy, OrderByAll, OrderByExpr, OrderByExprsWithInterpolate, PivotValueSource,
70+
ProjectionSelect, Query, RenameSelectItem, RepetitionQuantifier, ReplaceSelectElement,
71+
ReplaceSelectItem, RowsPerMatch, Select, SelectFlavor, SelectInto, SelectItem,
72+
SelectItemQualifiedWildcardKind, SetExpr, SetOperator, SetQuantifier, Setting,
73+
SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor, TableFunctionArgs,
74+
TableIndexHintForClause, TableIndexHintType, TableIndexHints, TableIndexType, TableSample,
75+
TableSampleBucket, TableSampleKind, TableSampleMethod, TableSampleModifier,
76+
TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier, TableSampleUnit, TableVersion,
77+
TableWithJoins, Top, TopQuantity, UpdateTableFromKind, ValueTableMode, Values,
78+
WildcardAdditionalOptions, With, WithFill,
7879
};
7980

8081
pub use self::trigger::{

src/ast/query.rs

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,31 +2205,50 @@ pub enum JoinConstraint {
22052205
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
22062206
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22072207
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2208-
pub struct OrderBy {
2209-
pub exprs: Vec<OrderByExpr>,
2210-
/// Optional: `INTERPOLATE`
2211-
/// Supported by [ClickHouse syntax]
2208+
pub enum OrderBy {
2209+
/// ALL syntax of [DuckDB] and [ClickHouse].
22122210
///
2213-
/// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
2214-
pub interpolate: Option<Interpolate>,
2211+
/// [DuckDB]: <https://duckdb.org/docs/sql/query_syntax/orderby>
2212+
/// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by>
2213+
All(OrderByAll),
2214+
2215+
/// Expressions
2216+
Expressions(OrderByExprsWithInterpolate),
22152217
}
22162218

22172219
impl fmt::Display for OrderBy {
22182220
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22192221
write!(f, "ORDER BY")?;
2220-
if !self.exprs.is_empty() {
2221-
write!(f, " {}", display_comma_separated(&self.exprs))?;
2222-
}
2223-
if let Some(ref interpolate) = self.interpolate {
2224-
match &interpolate.exprs {
2225-
Some(exprs) => write!(f, " INTERPOLATE ({})", display_comma_separated(exprs))?,
2226-
None => write!(f, " INTERPOLATE")?,
2222+
match self {
2223+
OrderBy::Expressions(exprs) => {
2224+
write!(f, "{}", exprs)?;
2225+
}
2226+
OrderBy::All(all) => {
2227+
write!(f, " ALL{}", all)?;
22272228
}
22282229
}
2230+
22292231
Ok(())
22302232
}
22312233
}
22322234

2235+
impl OrderBy {
2236+
pub fn get_exprs(&self) -> Option<&Vec<OrderByExpr>> {
2237+
match self {
2238+
OrderBy::Expressions(exprs_with_interpolate) => Some(&exprs_with_interpolate.exprs),
2239+
OrderBy::All(_) => None,
2240+
}
2241+
}
2242+
pub fn get_interpolate(&self) -> Option<&Interpolate> {
2243+
match self {
2244+
OrderBy::Expressions(exprs_with_interpolate) => {
2245+
exprs_with_interpolate.interpolate.as_ref()
2246+
}
2247+
OrderBy::All(_) => None,
2248+
}
2249+
}
2250+
}
2251+
22332252
/// An `ORDER BY` expression
22342253
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
22352254
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -2323,6 +2342,61 @@ impl fmt::Display for InterpolateExpr {
23232342
}
23242343
}
23252344

2345+
/// `ORDER BY` expressions with interpolate
2346+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2347+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2348+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2349+
pub struct OrderByExprsWithInterpolate {
2350+
pub exprs: Vec<OrderByExpr>,
2351+
/// Expressions
2352+
/// Optional: `INTERPOLATE`
2353+
/// Supported by [ClickHouse syntax]
2354+
/// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
2355+
pub interpolate: Option<Interpolate>,
2356+
}
2357+
2358+
impl fmt::Display for OrderByExprsWithInterpolate {
2359+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2360+
if !self.exprs.is_empty() {
2361+
write!(f, " {}", display_comma_separated(&self.exprs))?;
2362+
}
2363+
if let Some(ref interpolate) = self.interpolate {
2364+
match &interpolate.exprs {
2365+
Some(exprs) => write!(f, " INTERPOLATE ({})", display_comma_separated(exprs))?,
2366+
None => write!(f, " INTERPOLATE")?,
2367+
}
2368+
}
2369+
Ok(())
2370+
}
2371+
}
2372+
2373+
/// 'ORDER BY ALL' clause
2374+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2375+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2376+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2377+
pub struct OrderByAll {
2378+
/// Optional `ASC` or `DESC`
2379+
pub asc: Option<bool>,
2380+
/// Optional `NULLS FIRST` or `NULLS LAST`
2381+
pub nulls_first: Option<bool>,
2382+
}
2383+
2384+
impl fmt::Display for OrderByAll {
2385+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2386+
match self.asc {
2387+
Some(true) => write!(f, " ASC")?,
2388+
Some(false) => write!(f, " DESC")?,
2389+
None => (),
2390+
}
2391+
match self.nulls_first {
2392+
Some(true) => write!(f, " NULLS FIRST")?,
2393+
Some(false) => write!(f, " NULLS LAST")?,
2394+
None => (),
2395+
}
2396+
Ok(())
2397+
}
2398+
}
2399+
23262400
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
23272401
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23282402
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]

src/ast/spans.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,16 +1096,22 @@ impl Spanned for ProjectionSelect {
10961096
}
10971097
}
10981098

1099+
/// # partial span
1100+
///
1101+
/// Missing spans:
1102+
/// - [OrderByExpr::All]
10991103
impl Spanned for OrderBy {
11001104
fn span(&self) -> Span {
1101-
let OrderBy { exprs, interpolate } = self;
1102-
1103-
union_spans(
1104-
exprs
1105-
.iter()
1106-
.map(|i| i.span())
1107-
.chain(interpolate.iter().map(|i| i.span())),
1108-
)
1105+
match self {
1106+
OrderBy::All(_) => Span::empty(),
1107+
OrderBy::Expressions(expressions) => union_spans(
1108+
expressions
1109+
.exprs
1110+
.iter()
1111+
.map(|i| i.span())
1112+
.chain(expressions.interpolate.iter().map(|i| i.span())),
1113+
),
1114+
}
11091115
}
11101116
}
11111117

src/parser/mod.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9183,17 +9183,19 @@ impl<'a> Parser<'a> {
91839183

91849184
pub fn parse_optional_order_by(&mut self) -> Result<Option<OrderBy>, ParserError> {
91859185
if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
9186-
let order_by_exprs = self.parse_comma_separated(Parser::parse_order_by_expr)?;
9187-
let interpolate = if dialect_of!(self is ClickHouseDialect | GenericDialect) {
9188-
self.parse_interpolations()?
9186+
let order_by = if self.parse_keyword(Keyword::ALL) {
9187+
let order_by_all = self.parse_order_by_all()?;
9188+
OrderBy::All(order_by_all)
91899189
} else {
9190-
None
9190+
let exprs = self.parse_comma_separated(Parser::parse_order_by_expr)?;
9191+
let interpolate = if dialect_of!(self is ClickHouseDialect | GenericDialect) {
9192+
self.parse_interpolations()?
9193+
} else {
9194+
None
9195+
};
9196+
OrderBy::Expressions(OrderByExprsWithInterpolate { exprs, interpolate })
91919197
};
9192-
9193-
Ok(Some(OrderBy {
9194-
exprs: order_by_exprs,
9195-
interpolate,
9196-
}))
9198+
Ok(Some(order_by))
91979199
} else {
91989200
Ok(None)
91999201
}
@@ -13379,6 +13381,19 @@ impl<'a> Parser<'a> {
1337913381
})
1338013382
}
1338113383

13384+
pub fn parse_order_by_all(&mut self) -> Result<OrderByAll, ParserError> {
13385+
let asc = self.parse_asc_desc();
13386+
13387+
let nulls_first = if self.parse_keywords(&[Keyword::NULLS, Keyword::FIRST]) {
13388+
Some(true)
13389+
} else if self.parse_keywords(&[Keyword::NULLS, Keyword::LAST]) {
13390+
Some(false)
13391+
} else {
13392+
None
13393+
};
13394+
Ok(OrderByAll { asc, nulls_first })
13395+
}
13396+
1338213397
// Parse a WITH FILL clause (ClickHouse dialect)
1338313398
// that follow the WITH FILL keywords in a ORDER BY clause
1338413399
pub fn parse_with_fill(&mut self) -> Result<WithFill, ParserError> {

tests/sqlparser_clickhouse.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,15 +322,15 @@ fn parse_alter_table_add_projection() {
322322
vec![Identifier(Ident::new("a"))],
323323
vec![]
324324
)),
325-
order_by: Some(OrderBy {
325+
order_by: Some(OrderBy::Expressions(OrderByExprsWithInterpolate {
326326
exprs: vec![OrderByExpr {
327327
expr: Identifier(Ident::new("b")),
328328
asc: None,
329329
nulls_first: None,
330330
with_fill: None,
331331
}],
332332
interpolate: None,
333-
}),
333+
})),
334334
}
335335
}
336336
)
@@ -1134,7 +1134,7 @@ fn parse_select_order_by_with_fill_interpolate() {
11341134
LIMIT 2";
11351135
let select = clickhouse().verified_query(sql);
11361136
assert_eq!(
1137-
OrderBy {
1137+
OrderBy::Expressions(OrderByExprsWithInterpolate {
11381138
exprs: vec![
11391139
OrderByExpr {
11401140
expr: Expr::Identifier(Ident::new("fname")),
@@ -1167,7 +1167,7 @@ fn parse_select_order_by_with_fill_interpolate() {
11671167
}),
11681168
}])
11691169
})
1170-
},
1170+
}),
11711171
select.order_by.expect("ORDER BY expected")
11721172
);
11731173
assert_eq!(Some(Expr::Value(number("2"))), select.limit);
@@ -1215,7 +1215,12 @@ fn parse_with_fill() {
12151215
to: Some(Expr::Value(number("20"))),
12161216
step: Some(Expr::Value(number("2"))),
12171217
}),
1218-
select.order_by.expect("ORDER BY expected").exprs[0].with_fill
1218+
select
1219+
.order_by
1220+
.expect("ORDER BY expected")
1221+
.get_exprs()
1222+
.unwrap()[0]
1223+
.with_fill
12191224
);
12201225
}
12211226

@@ -1266,8 +1271,12 @@ fn parse_interpolate_body_with_columns() {
12661271
}),
12671272
},
12681273
])
1269-
}),
1270-
select.order_by.expect("ORDER BY expected").interpolate
1274+
})
1275+
.as_ref(),
1276+
select
1277+
.order_by
1278+
.expect("ORDER BY expected")
1279+
.get_interpolate()
12711280
);
12721281
}
12731282

@@ -1276,8 +1285,11 @@ fn parse_interpolate_without_body() {
12761285
let sql = "SELECT fname FROM customer ORDER BY fname WITH FILL INTERPOLATE";
12771286
let select = clickhouse().verified_query(sql);
12781287
assert_eq!(
1279-
Some(Interpolate { exprs: None }),
1280-
select.order_by.expect("ORDER BY expected").interpolate
1288+
Some(Interpolate { exprs: None }).as_ref(),
1289+
select
1290+
.order_by
1291+
.expect("ORDER BY expected")
1292+
.get_interpolate()
12811293
);
12821294
}
12831295

@@ -1288,8 +1300,12 @@ fn parse_interpolate_with_empty_body() {
12881300
assert_eq!(
12891301
Some(Interpolate {
12901302
exprs: Some(vec![])
1291-
}),
1292-
select.order_by.expect("ORDER BY expected").interpolate
1303+
})
1304+
.as_ref(),
1305+
select
1306+
.order_by
1307+
.expect("ORDER BY expected")
1308+
.get_interpolate()
12931309
);
12941310
}
12951311

0 commit comments

Comments
 (0)