Skip to content

Commit e4ef3cf

Browse files
committed
make tests pass
1 parent 202582c commit e4ef3cf

File tree

4 files changed

+79
-38
lines changed

4 files changed

+79
-38
lines changed

src/ast/mod.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,22 @@ pub use self::dml::{CreateIndex, CreateTable, Delete, IndexColumn, Insert};
6262
pub use self::operator::{BinaryOperator, UnaryOperator};
6363
pub use self::query::{
6464
AfterMatchSkip, ConnectBy, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
65-
ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, Fetch, ForClause, ForJson, ForXml,
66-
FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias, IlikeSelectItem,
67-
InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint, JoinOperator,
68-
JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn, JsonTableNestedColumn,
69-
LateralView, LockClause, LockType, MatchRecognizePattern, MatchRecognizeSymbol, Measure,
70-
NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset, OffsetRows, OpenJsonTableColumn,
71-
OrderBy, OrderByExpr, OrderByKind, OrderByOptions, PipeOperator, PivotValueSource,
72-
ProjectionSelect, Query, RenameSelectItem, RepetitionQuantifier, ReplaceSelectElement,
73-
ReplaceSelectItem, RowsPerMatch, Select, SelectFlavor, SelectInto, SelectItem,
74-
SelectItemQualifiedWildcardKind, SetExpr, SetOperator, SetQuantifier, Setting,
75-
SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor, TableFunctionArgs,
76-
TableIndexHintForClause, TableIndexHintType, TableIndexHints, TableIndexType, TableSample,
77-
TableSampleBucket, TableSampleKind, TableSampleMethod, TableSampleModifier,
78-
TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier, TableSampleUnit, TableVersion,
79-
TableWithJoins, Top, TopQuantity, UpdateTableFromKind, ValueTableMode, Values,
80-
WildcardAdditionalOptions, With, WithFill,
65+
ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, ExprWithAliasAndOrderBy, Fetch, ForClause,
66+
ForJson, ForXml, FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias,
67+
IlikeSelectItem, InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint,
68+
JoinOperator, JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn,
69+
JsonTableNestedColumn, LateralView, LockClause, LockType, MatchRecognizePattern,
70+
MatchRecognizeSymbol, Measure, NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset,
71+
OffsetRows, OpenJsonTableColumn, OrderBy, OrderByExpr, OrderByKind, OrderByOptions,
72+
PipeOperator, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
73+
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
74+
SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator,
75+
SetQuantifier, Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
76+
TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
77+
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
78+
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
79+
TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
80+
ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
8181
};
8282

8383
pub use self::trigger::{

src/ast/query.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,26 @@ impl fmt::Display for ExprWithAlias {
10191019
}
10201020
}
10211021

1022+
/// An expression optionally followed by an alias and order by options.
1023+
///
1024+
/// Example:
1025+
/// ```sql
1026+
/// 42 AS myint ASC
1027+
/// ```
1028+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1029+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1030+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1031+
pub struct ExprWithAliasAndOrderBy {
1032+
pub expr: ExprWithAlias,
1033+
pub order_by: OrderByOptions,
1034+
}
1035+
1036+
impl fmt::Display for ExprWithAliasAndOrderBy {
1037+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1038+
write!(f, "{}{}", self.expr, self.order_by)
1039+
}
1040+
}
1041+
10221042
/// Arguments to a table-valued function
10231043
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10241044
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -2484,8 +2504,8 @@ pub enum PipeOperator {
24842504
///
24852505
/// See more at https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax#aggregate_pipe_operator
24862506
Aggregate {
2487-
full_table_exprs: Vec<ExprWithAlias>,
2488-
group_by_exprs: Vec<ExprWithAlias>,
2507+
full_table_exprs: Vec<ExprWithAliasAndOrderBy>,
2508+
group_by_expr: Vec<ExprWithAliasAndOrderBy>,
24892509
},
24902510
}
24912511

@@ -2516,7 +2536,7 @@ impl fmt::Display for PipeOperator {
25162536
}
25172537
PipeOperator::Aggregate {
25182538
full_table_exprs,
2519-
group_by_exprs,
2539+
group_by_expr,
25202540
} => {
25212541
write!(f, "AGGREGATE")?;
25222542
if !full_table_exprs.is_empty() {
@@ -2526,12 +2546,8 @@ impl fmt::Display for PipeOperator {
25262546
display_comma_separated(full_table_exprs.as_slice())
25272547
)?;
25282548
}
2529-
if !group_by_exprs.is_empty() {
2530-
write!(
2531-
f,
2532-
" GROUP BY {}",
2533-
display_comma_separated(group_by_exprs.as_slice())
2534-
)?;
2549+
if !group_by_expr.is_empty() {
2550+
write!(f, " GROUP BY {}", display_comma_separated(group_by_expr))?;
25352551
}
25362552
Ok(())
25372553
}

src/parser/mod.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,25 @@ impl<'a> Parser<'a> {
10151015
self.parse_subexpr(self.dialect.prec_unknown())
10161016
}
10171017

1018+
pub fn parse_expr_with_alias_and_order_by(
1019+
&mut self,
1020+
) -> Result<ExprWithAliasAndOrderBy, ParserError> {
1021+
let expr = self.parse_expr()?;
1022+
1023+
fn validator(explicit: bool, kw: &Keyword, _parser: &mut Parser) -> bool {
1024+
explicit || !&[Keyword::ASC, Keyword::DESC, Keyword::GROUP].contains(kw)
1025+
}
1026+
let alias = self.parse_optional_alias_inner(None, validator)?;
1027+
let order_by = OrderByOptions {
1028+
asc: self.parse_asc_desc(),
1029+
nulls_first: None,
1030+
};
1031+
Ok(ExprWithAliasAndOrderBy {
1032+
expr: ExprWithAlias { expr, alias },
1033+
order_by,
1034+
})
1035+
}
1036+
10181037
/// Parse tokens until the precedence changes.
10191038
pub fn parse_subexpr(&mut self, precedence: u8) -> Result<Expr, ParserError> {
10201039
let _guard = self.recursion_counter.try_decrease()?;
@@ -10391,27 +10410,25 @@ impl<'a> Parser<'a> {
1039110410
pipe_operators.push(PipeOperator::Limit { expr, offset })
1039210411
}
1039310412
Keyword::AGGREGATE => {
10394-
let full_table_exprs = self.parse_comma_separated0(
10395-
|parser| {
10396-
let expr = parser.parse_expr()?;
10397-
let alias = parser.maybe_parse_select_item_alias()?;
10398-
Ok(ExprWithAlias { expr, alias })
10399-
},
10400-
Token::make_keyword(keywords::GROUP),
10401-
)?;
10413+
let full_table_exprs = if self.peek_keyword(Keyword::GROUP) {
10414+
vec![]
10415+
} else {
10416+
self.parse_comma_separated(|parser| {
10417+
parser.parse_expr_with_alias_and_order_by()
10418+
})?
10419+
};
1040210420

10403-
let group_by_exprs = if self.parse_keywords(&[Keyword::GROUP, Keyword::BY]) {
10421+
let group_by_expr = if self.parse_keywords(&[Keyword::GROUP, Keyword::BY]) {
1040410422
self.parse_comma_separated(|parser| {
10405-
let expr = parser.parse_expr()?;
10406-
let alias = parser.maybe_parse_select_item_alias()?;
10407-
Ok(ExprWithAlias { expr, alias })
10423+
parser.parse_expr_with_alias_and_order_by()
1040810424
})?
1040910425
} else {
1041010426
vec![]
1041110427
};
10428+
1041210429
pipe_operators.push(PipeOperator::Aggregate {
1041310430
full_table_exprs,
10414-
group_by_exprs,
10431+
group_by_expr,
1041510432
})
1041610433
}
1041710434
Keyword::ORDER => {

tests/sqlparser_common.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14724,9 +14724,17 @@ fn parse_pipeline_operator() {
1472414724
);
1472514725
dialects
1472614726
.verified_stmt("SELECT * FROM users |> AGGREGATE GROUP BY EXTRACT(YEAR FROM o_orderdate)");
14727+
dialects.verified_stmt("SELECT * FROM users |> AGGREGATE GROUP BY a, b");
14728+
dialects.verified_stmt("SELECT * FROM users |> AGGREGATE SUM(c) GROUP BY a, b");
14729+
dialects.verified_stmt("SELECT * FROM users |> AGGREGATE SUM(c) ASC");
1472714730

1472814731
// order by pipe operator
1472914732
dialects.verified_stmt("SELECT * FROM users |> ORDER BY id ASC");
1473014733
dialects.verified_stmt("SELECT * FROM users |> ORDER BY id DESC");
1473114734
dialects.verified_stmt("SELECT * FROM users |> ORDER BY id DESC, name ASC");
14735+
14736+
// many pipes
14737+
dialects.verified_stmt(
14738+
"SELECT * FROM CustomerOrders |> AGGREGATE SUM(cost) AS total_cost GROUP BY customer_id, state, item_type |> EXTEND COUNT(*) OVER (PARTITION BY customer_id) AS num_orders |> WHERE num_orders > 1 |> AGGREGATE AVG(total_cost) AS average GROUP BY state DESC, item_type ASC",
14739+
);
1473214740
}

0 commit comments

Comments
 (0)