diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4d86dd6a6..6a5a4f13c 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -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 + /// (expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...) + /// ``` + pub within_group: Vec, /// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)` pub filter: Option>, /// Indicates how `NULL`s should be handled in the calculation. @@ -8231,14 +8239,6 @@ pub struct Function { pub null_treatment: Option, /// The `OVER` clause, indicating a window function call. pub over: Option, - /// A clause used with certain aggregate functions to control the ordering - /// within grouped sets before the function is applied. - /// - /// Syntax: - /// ```plaintext - /// (expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...) - /// ``` - pub within_group: Vec, } impl fmt::Display for Function { diff --git a/src/ast/visitor.rs b/src/ast/visitor.rs index 9011a94d5..2518fdd37 100644 --- a/src/ast/visitor.rs +++ b/src/ast/visitor.rs @@ -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, + } + + impl Visitor for ExprVisitor { + type Break = (); + + fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow { + 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)]