From a74cc1fa50ed880ce5a938539d5f3aca8f2007cb Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 19 Jul 2024 18:46:52 +0800 Subject: [PATCH 1/2] Allow to use `()` as the GROUP BY nothing for PostgreSQL Currently, PostgreSQL supports using `()` as one of the group by elements which represent the meaning of nothing. Please refer to GROUP BY Clause section in [PostgreSQL](https://www.postgresql.org/docs/16/sql-select.html). This PR will close #1092. --- src/parser/mod.rs | 5 +++++ tests/sqlparser_postgres.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d00f28a55..0f1c80941 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1474,6 +1474,11 @@ impl<'a> Parser<'a> { let result = self.parse_comma_separated(|p| p.parse_tuple(true, true))?; self.expect_token(&Token::RParen)?; Ok(Expr::Rollup(result)) + } else if self.consume_tokens(&[Token::LParen, Token::RParen]) { + // PostgreSQL allow to use empty tuple as a group by expression, + // e.g. `GROUP BY (), name`. Please refer to GROUP BY Clause section in + // [PostgreSQL](https://www.postgresql.org/docs/16/sql-select.html) + Ok(Expr::Tuple(vec![])) } else { self.parse_expr() } diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index ed17e9d8f..f734ffacd 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -18,6 +18,7 @@ mod test_utils; use test_utils::*; +use sqlparser::ast::Expr::Identifier; use sqlparser::ast::*; use sqlparser::dialect::{GenericDialect, PostgreSqlDialect}; use sqlparser::parser::ParserError; @@ -4441,3 +4442,30 @@ fn test_table_unnest_with_ordinality() { _ => panic!("Expecting TableFactor::UNNEST with ordinality"), } } + +#[test] +fn test_group_by_nothing() { + let Select { group_by, .. } = + pg_and_generic().verified_only_select("SELECT count(1) FROM t GROUP BY ()"); + { + assert_eq!( + GroupByExpr::Expressions(vec![Expr::Tuple(vec![])], vec![]), + group_by + ); + } + + let Select { group_by, .. } = + pg_and_generic().verified_only_select("SELECT name, count(1) FROM t GROUP BY name, ()"); + { + assert_eq!( + GroupByExpr::Expressions( + vec![ + Identifier(Ident::new("name".to_string())), + Expr::Tuple(vec![]) + ], + vec![] + ), + group_by + ); + } +} From 70dcc31010dd6de5aa02a36bb73d171efc82c44e Mon Sep 17 00:00:00 2001 From: git-hulk Date: Sun, 21 Jul 2024 15:38:33 +0800 Subject: [PATCH 2/2] Move the group by nothing test case to common --- tests/sqlparser_common.rs | 28 ++++++++++++++++++++++++++++ tests/sqlparser_postgres.rs | 28 ---------------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 1adda149e..25177c38b 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -42,6 +42,7 @@ mod test_utils; #[cfg(test)] use pretty_assertions::assert_eq; +use sqlparser::ast::Expr::Identifier; use sqlparser::test_utils::all_dialects_except; #[test] @@ -10131,3 +10132,30 @@ fn parse_auto_increment_too_large() { assert!(res.is_err(), "{res:?}"); } + +#[test] +fn test_group_by_nothing() { + let Select { group_by, .. } = all_dialects_where(|d| d.supports_group_by_expr()) + .verified_only_select("SELECT count(1) FROM t GROUP BY ()"); + { + std::assert_eq!( + GroupByExpr::Expressions(vec![Expr::Tuple(vec![])], vec![]), + group_by + ); + } + + let Select { group_by, .. } = all_dialects_where(|d| d.supports_group_by_expr()) + .verified_only_select("SELECT name, count(1) FROM t GROUP BY name, ()"); + { + std::assert_eq!( + GroupByExpr::Expressions( + vec![ + Identifier(Ident::new("name".to_string())), + Expr::Tuple(vec![]) + ], + vec![] + ), + group_by + ); + } +} diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index f734ffacd..ed17e9d8f 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -18,7 +18,6 @@ mod test_utils; use test_utils::*; -use sqlparser::ast::Expr::Identifier; use sqlparser::ast::*; use sqlparser::dialect::{GenericDialect, PostgreSqlDialect}; use sqlparser::parser::ParserError; @@ -4442,30 +4441,3 @@ fn test_table_unnest_with_ordinality() { _ => panic!("Expecting TableFactor::UNNEST with ordinality"), } } - -#[test] -fn test_group_by_nothing() { - let Select { group_by, .. } = - pg_and_generic().verified_only_select("SELECT count(1) FROM t GROUP BY ()"); - { - assert_eq!( - GroupByExpr::Expressions(vec![Expr::Tuple(vec![])], vec![]), - group_by - ); - } - - let Select { group_by, .. } = - pg_and_generic().verified_only_select("SELECT name, count(1) FROM t GROUP BY name, ()"); - { - assert_eq!( - GroupByExpr::Expressions( - vec![ - Identifier(Ident::new("name".to_string())), - Expr::Tuple(vec![]) - ], - vec![] - ), - group_by - ); - } -}