diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 480f0d23..23f23308 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -4962,6 +4962,10 @@ pub enum FunctionArgumentClause { /// /// See . OnOverflow(ListAggOnOverflow), + /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL. + /// + /// [`GROUP_CONCAT`]: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat + Separator(Value), } impl fmt::Display for FunctionArgumentClause { @@ -4975,6 +4979,7 @@ impl fmt::Display for FunctionArgumentClause { } FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"), FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"), + FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"), } } } diff --git a/src/keywords.rs b/src/keywords.rs index 73d388cf..e67fffd9 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -616,6 +616,7 @@ define_keywords!( SELECT, SEMI, SENSITIVE, + SEPARATOR, SEQUENCE, SEQUENCEFILE, SEQUENCES, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index fbc07eee..6e52d422 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9488,6 +9488,12 @@ impl<'a> Parser<'a> { clauses.push(FunctionArgumentClause::Limit(self.parse_expr()?)); } + if dialect_of!(self is GenericDialect | MySqlDialect) + && self.parse_keyword(Keyword::SEPARATOR) + { + clauses.push(FunctionArgumentClause::Separator(self.parse_value()?)); + } + if let Some(on_overflow) = self.parse_listagg_on_overflow()? { clauses.push(FunctionArgumentClause::OnOverflow(on_overflow)); } diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 6a71a44d..516775da 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -2706,3 +2706,14 @@ fn parse_json_table() { } ); } + +#[test] +fn test_group_concat() { + // examples taken from mysql docs + // https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat + mysql_and_generic().verified_expr("GROUP_CONCAT(DISTINCT test_score)"); + mysql_and_generic().verified_expr("GROUP_CONCAT(test_score ORDER BY test_score)"); + mysql_and_generic().verified_expr("GROUP_CONCAT(test_score SEPARATOR ' ')"); + mysql_and_generic() + .verified_expr("GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ')"); +}