From 4ece53265203d2fc777cc126db64360acfbf5805 Mon Sep 17 00:00:00 2001 From: 2748109647 <196059414+2748109647@users.noreply.github.com> Date: Sat, 17 Oct 2026 06:21:41 +0800 Subject: [PATCH] fix: parse PostgreSQL GROUP BY DISTINCT --- .../jsqlparser/statement/select/GroupByElement.java | 13 +++++++++++++ .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 1 + .../sf/jsqlparser/statement/select/SelectTest.java | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java index b0ba784b7..82283e0b4 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java @@ -33,11 +33,21 @@ public enum SortDirection { private List> groupingSets = new ArrayList<>(); // postgres rollup is an ExpressionList private boolean mysqlWithRollup = false; + private boolean distinct = false; public boolean isUsingBrackets() { return groupByExpressions.isUsingBrackets(); } + public boolean isDistinct() { + return distinct; + } + + public GroupByElement setDistinct(boolean distinct) { + this.distinct = distinct; + return this; + } + public T accept(GroupByVisitor groupByVisitor, S context) { return groupByVisitor.visit(this, context); } @@ -115,6 +125,9 @@ public String toString() { public void appendTo(StringBuilder builder, Consumer> listRenderer, Consumer expressionRenderer) { builder.append("GROUP BY "); + if (distinct) { + builder.append("DISTINCT "); + } if (groupByExpressions != null) { if (hasGroupBySortDirections()) { appendOrderedExpressions(builder, expressionRenderer); diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 2210dbe9d..08ba29bfc 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -10452,6 +10452,7 @@ GroupByElement GroupByColumnReferences(): } { + [ LOOKAHEAD() { groupBy.setDistinct(true); } ] ( LOOKAHEAD(2) ( diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java index a09ab4be3..045ed7eed 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -4792,6 +4792,13 @@ public void testGroupingSets3() throws JSQLParserException { "SELECT COL_1 FROM TABLE_1 GROUP BY GROUPING SETS (COL_1, ())"); } + @Test + public void testGroupingSetsDistinctIssue2785() throws JSQLParserException { + PlainSelect select = (PlainSelect) assertSqlCanBeParsedAndDeparsed( + "SELECT 1 GROUP BY DISTINCT GROUPING SETS ((1), (1))"); + assertTrue(select.getGroupBy().isDistinct()); + } + @Test public void testLongQualifiedNamesIssue763() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(