Add support for multiple expressions, order by in aggregations (#879)

* Add support for multiple expressions, order by in aggregations

* Fix formatting errors

* Resolve linter errors
This commit is contained in:
Mustafa Akur 2023-05-17 20:04:33 +03:00 committed by GitHub
parent ae3b5844c8
commit 482a3ad417
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 8 deletions

View file

@ -3518,7 +3518,7 @@ impl fmt::Display for ListAggOnOverflow {
pub struct ArrayAgg { pub struct ArrayAgg {
pub distinct: bool, pub distinct: bool,
pub expr: Box<Expr>, pub expr: Box<Expr>,
pub order_by: Option<Box<OrderByExpr>>, pub order_by: Option<Vec<OrderByExpr>>,
pub limit: Option<Box<Expr>>, pub limit: Option<Box<Expr>>,
pub within_group: bool, // order by is used inside a within group or not pub within_group: bool, // order by is used inside a within group or not
} }
@ -3533,7 +3533,7 @@ impl fmt::Display for ArrayAgg {
)?; )?;
if !self.within_group { if !self.within_group {
if let Some(order_by) = &self.order_by { if let Some(order_by) = &self.order_by {
write!(f, " ORDER BY {order_by}")?; write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
} }
if let Some(limit) = &self.limit { if let Some(limit) = &self.limit {
write!(f, " LIMIT {limit}")?; write!(f, " LIMIT {limit}")?;
@ -3542,7 +3542,11 @@ impl fmt::Display for ArrayAgg {
write!(f, ")")?; write!(f, ")")?;
if self.within_group { if self.within_group {
if let Some(order_by) = &self.order_by { if let Some(order_by) = &self.order_by {
write!(f, " WITHIN GROUP (ORDER BY {order_by})")?; write!(
f,
" WITHIN GROUP (ORDER BY {})",
display_comma_separated(order_by)
)?;
} }
} }
Ok(()) Ok(())

View file

@ -1369,8 +1369,7 @@ impl<'a> Parser<'a> {
// ANSI SQL and BigQuery define ORDER BY inside function. // ANSI SQL and BigQuery define ORDER BY inside function.
if !self.dialect.supports_within_after_array_aggregation() { if !self.dialect.supports_within_after_array_aggregation() {
let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) { let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
let order_by_expr = self.parse_order_by_expr()?; Some(self.parse_comma_separated(Parser::parse_order_by_expr)?)
Some(Box::new(order_by_expr))
} else { } else {
None None
}; };
@ -1393,10 +1392,13 @@ impl<'a> Parser<'a> {
self.expect_token(&Token::RParen)?; self.expect_token(&Token::RParen)?;
let within_group = if self.parse_keywords(&[Keyword::WITHIN, Keyword::GROUP]) { let within_group = if self.parse_keywords(&[Keyword::WITHIN, Keyword::GROUP]) {
self.expect_token(&Token::LParen)?; self.expect_token(&Token::LParen)?;
self.expect_keywords(&[Keyword::ORDER, Keyword::BY])?; let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
let order_by_expr = self.parse_order_by_expr()?; Some(self.parse_comma_separated(Parser::parse_order_by_expr)?)
} else {
None
};
self.expect_token(&Token::RParen)?; self.expect_token(&Token::RParen)?;
Some(Box::new(order_by_expr)) order_by
} else { } else {
None None
}; };

View file

@ -2065,6 +2065,8 @@ fn parse_array_agg_func() {
"SELECT ARRAY_AGG(x ORDER BY x) AS a FROM T", "SELECT ARRAY_AGG(x ORDER BY x) AS a FROM T",
"SELECT ARRAY_AGG(x ORDER BY x LIMIT 2) FROM tbl", "SELECT ARRAY_AGG(x ORDER BY x LIMIT 2) FROM tbl",
"SELECT ARRAY_AGG(DISTINCT x ORDER BY x LIMIT 2) FROM tbl", "SELECT ARRAY_AGG(DISTINCT x ORDER BY x LIMIT 2) FROM tbl",
"SELECT ARRAY_AGG(x ORDER BY x, y) AS a FROM T",
"SELECT ARRAY_AGG(x ORDER BY x ASC, y DESC) AS a FROM T",
] { ] {
supported_dialects.verified_stmt(sql); supported_dialects.verified_stmt(sql);
} }