Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8218,6 +8218,14 @@ pub struct Function {
/// The arguments to the function, including any options specified within the
/// delimiting parentheses.
pub args: FunctionArguments,
/// A clause used with certain aggregate functions to control the ordering
/// within grouped sets before the function is applied.
///
/// Syntax:
/// ```plaintext
/// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
/// ```
pub within_group: Vec<OrderByExpr>,
/// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)`
pub filter: Option<Box<Expr>>,
/// Indicates how `NULL`s should be handled in the calculation.
Expand All @@ -8231,14 +8239,6 @@ pub struct Function {
pub null_treatment: Option<NullTreatment>,
/// The `OVER` clause, indicating a window function call.
pub over: Option<WindowType>,
/// A clause used with certain aggregate functions to control the ordering
/// within grouped sets before the function is applied.
///
/// Syntax:
/// ```plaintext
/// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
/// ```
pub within_group: Vec<OrderByExpr>,
}

impl fmt::Display for Function {
Expand Down
26 changes: 26 additions & 0 deletions src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,32 @@ mod tests {
do_visit("SELECT a, b FROM t", &mut visitor);
assert_eq!(visitor.idents, vec!["a", "b", "t"]);
}

#[test]
fn visits_function_clauses_in_source_order() {
#[derive(Default)]
struct ExprVisitor {
idents: Vec<String>,
}

impl Visitor for ExprVisitor {
type Break = ();

fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
if let Expr::Identifier(ident) = expr {
self.idents.push(ident.value.clone());
}
ControlFlow::Continue(())
}
}

let mut visitor = ExprVisitor::default();
do_visit(
"SELECT LISTAGG(value) WITHIN GROUP (ORDER BY order_key) FILTER (WHERE filter_key)",
&mut visitor,
);
assert_eq!(visitor.idents, ["value", "order_key", "filter_key"]);
}
}

#[cfg(test)]
Expand Down
Loading