Add support for first, last aggregate function parsing (#882)

* Add order by parsing to functions

* Fix doc error

* minor changes
This commit is contained in:
Mustafa Akur 2023-05-18 21:59:14 +03:00 committed by GitHub
parent 33b12acce7
commit 1b86abebe2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 7 deletions

View file

@ -3366,6 +3366,8 @@ pub struct Function {
// Some functions must be called without trailing parentheses, for example Postgres
// do it for current_catalog, current_schema, etc. This flags is used for formatting.
pub special: bool,
// Required ordering for the function (if empty, there is no requirement).
pub order_by: Vec<OrderByExpr>,
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
@ -3392,12 +3394,18 @@ impl fmt::Display for Function {
if self.special {
write!(f, "{}", self.name)?;
} else {
let order_by = if !self.order_by.is_empty() {
" ORDER BY "
} else {
""
};
write!(
f,
"{}({}{})",
"{}({}{}{order_by}{})",
self.name,
if self.distinct { "DISTINCT " } else { "" },
display_comma_separated(&self.args),
display_comma_separated(&self.order_by),
)?;
if let Some(o) = &self.over {

View file

@ -480,7 +480,7 @@ where
/// *expr = Expr::Function(Function {
/// name: ObjectName(vec![Ident::new("f")]),
/// args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(old_expr))],
/// over: None, distinct: false, special: false,
/// over: None, distinct: false, special: false, order_by: vec![],
/// });
/// }
/// ControlFlow::<()>::Continue(())

View file

@ -706,6 +706,7 @@ impl<'a> Parser<'a> {
over: None,
distinct: false,
special: true,
order_by: vec![],
}))
}
Keyword::CURRENT_TIMESTAMP
@ -881,7 +882,7 @@ impl<'a> Parser<'a> {
pub fn parse_function(&mut self, name: ObjectName) -> Result<Expr, ParserError> {
self.expect_token(&Token::LParen)?;
let distinct = self.parse_all_or_distinct()?.is_some();
let args = self.parse_optional_args()?;
let (args, order_by) = self.parse_optional_args_with_orderby()?;
let over = if self.parse_keyword(Keyword::OVER) {
// TBD: support window names (`OVER mywin`) in place of inline specification
self.expect_token(&Token::LParen)?;
@ -918,14 +919,15 @@ impl<'a> Parser<'a> {
over,
distinct,
special: false,
order_by,
}))
}
pub fn parse_time_functions(&mut self, name: ObjectName) -> Result<Expr, ParserError> {
let args = if self.consume_token(&Token::LParen) {
self.parse_optional_args()?
let (args, order_by) = if self.consume_token(&Token::LParen) {
self.parse_optional_args_with_orderby()?
} else {
vec![]
(vec![], vec![])
};
Ok(Expr::Function(Function {
name,
@ -933,6 +935,7 @@ impl<'a> Parser<'a> {
over: None,
distinct: false,
special: false,
order_by,
}))
}
@ -6376,6 +6379,23 @@ impl<'a> Parser<'a> {
}
}
pub fn parse_optional_args_with_orderby(
&mut self,
) -> Result<(Vec<FunctionArg>, Vec<OrderByExpr>), ParserError> {
if self.consume_token(&Token::RParen) {
Ok((vec![], vec![]))
} else {
let args = self.parse_comma_separated(Parser::parse_function_args)?;
let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
self.parse_comma_separated(Parser::parse_order_by_expr)?
} else {
vec![]
};
self.expect_token(&Token::RParen)?;
Ok((args, order_by))
}
}
/// Parse a comma-delimited list of projections after SELECT
pub fn parse_select_item(&mut self) -> Result<SelectItem, ParserError> {
match self.parse_wildcard_expr()? {