From c0be23d7c599d9d3e780c2dbb8103d70a987403f Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sun, 5 Aug 2012 23:00:06 +0200 Subject: [PATCH] [#1665] Add support for the empty GROUP BY () clause --- .../jooq/test/_/testcases/GroupByTests.java | 14 +++++++++++++ .../src/main/resources/manual-2.5.xml | 14 +++++++++++++ .../main/java/org/jooq/SelectGroupByStep.java | 6 ++++++ jOOQ/src/main/java/org/jooq/SelectQuery.java | 6 ++++++ .../java/org/jooq/impl/AbstractSubSelect.java | 20 ++++++++++++++----- .../java/org/jooq/impl/SelectQueryImpl.java | 1 + .../src/test/java/org/jooq/test/jOOQTest.java | 5 +++++ 7 files changed, 61 insertions(+), 5 deletions(-) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java index 1326dc3911..330d3c1ce4 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java @@ -47,6 +47,7 @@ import static org.jooq.impl.Factory.groupingId; import static org.jooq.impl.Factory.groupingSets; import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.rollup; +import static org.jooq.impl.Factory.trueCondition; import java.util.Arrays; @@ -90,6 +91,19 @@ extends BaseTest count = count().as("c"); Result result = create() diff --git a/jOOQ-website/src/main/resources/manual-2.5.xml b/jOOQ-website/src/main/resources/manual-2.5.xml index 64d6c07fdd..4979ff6108 100644 --- a/jOOQ-website/src/main/resources/manual-2.5.xml +++ b/jOOQ-website/src/main/resources/manual-2.5.xml @@ -1341,6 +1341,20 @@ GROUP BY AUTHOR_ID]]> This will return an arbitrary title per author. jOOQ supports this syntax, as jOOQ is not doing any checks internally, about the consistence of tables/fields/functions that you provide it.

+

Empty GROUP BY clauses

+

+ jOOQ supports empty GROUP BY () clauses as well. This will result in that return only one record. +

+ + + + + +

ROLLUP(), CUBE() and GROUPING SETS()

Some databases support the SQL standard grouping functions and some extensions thereof. See the manual's section about for more details. diff --git a/jOOQ/src/main/java/org/jooq/SelectGroupByStep.java b/jOOQ/src/main/java/org/jooq/SelectGroupByStep.java index 75c0433a5a..850d1b9cb1 100644 --- a/jOOQ/src/main/java/org/jooq/SelectGroupByStep.java +++ b/jOOQ/src/main/java/org/jooq/SelectGroupByStep.java @@ -83,12 +83,18 @@ public interface SelectGroupByStep extends SelectHavingStep { /** * Add a GROUP BY clause to the query + *

+ * Calling this with an empty argument list will result in an empty + * GROUP BY () clause being rendered. */ @Support SelectHavingStep groupBy(Field... fields); /** * Add a GROUP BY clause to the query + *

+ * Calling this with an empty argument list will result in an empty + * GROUP BY () clause being rendered. */ @Support SelectHavingStep groupBy(Collection> fields); diff --git a/jOOQ/src/main/java/org/jooq/SelectQuery.java b/jOOQ/src/main/java/org/jooq/SelectQuery.java index 21e55bf7f8..06d1f807d4 100644 --- a/jOOQ/src/main/java/org/jooq/SelectQuery.java +++ b/jOOQ/src/main/java/org/jooq/SelectQuery.java @@ -187,6 +187,9 @@ public interface SelectQuery extends Select, ConditionProvider, OrderPro /** * Adds grouping fields + *

+ * Calling this with an empty argument list will result in an empty + * GROUP BY () clause being rendered. * * @param fields The grouping fields */ @@ -195,6 +198,9 @@ public interface SelectQuery extends Select, ConditionProvider, OrderPro /** * Adds grouping fields + *

+ * Calling this with an empty argument list will result in an empty + * GROUP BY () clause being rendered. * * @param fields The grouping fields */ diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractSubSelect.java b/jOOQ/src/main/java/org/jooq/impl/AbstractSubSelect.java index 969b4596ab..37f78c28ba 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractSubSelect.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractSubSelect.java @@ -96,14 +96,13 @@ implements private final ConditionProviderImpl connectBy; private boolean connectByNoCycle; private final ConditionProviderImpl connectByStartWith; + private boolean grouping; private final FieldList groupBy; private final ConditionProviderImpl having; private final SortFieldList orderBy; private boolean orderBySiblings; private final Limit limit; - - AbstractSubSelect(Configuration configuration) { this(configuration, null); } @@ -506,10 +505,17 @@ implements // GROUP BY and HAVING clause // -------------------------- - if (!getGroupBy().isEmpty()) { + if (grouping) { context.formatSeparator() - .keyword("group by ") - .sql(getGroupBy()); + .keyword("group by "); + + // [#1665] Empty GROUP BY () clauses need parentheses + if (getGroupBy().isEmpty()) { + context.sql("()"); + } + else { + context.sql(getGroupBy()); + } } if (!(getHaving().getWhere() instanceof TrueCondition)) { @@ -724,6 +730,10 @@ implements return from; } + final void setGrouping() { + grouping = true; + } + final FieldList getGroupBy() { return groupBy; } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 81578e57fa..c2dad3041e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -105,6 +105,7 @@ class SelectQueryImpl extends AbstractSubSelect implements SelectQuery { @Override public final void addGroupBy(Collection> fields) { + setGrouping(); getGroupBy().addAll(fields); } diff --git a/jOOQ/src/test/java/org/jooq/test/jOOQTest.java b/jOOQ/src/test/java/org/jooq/test/jOOQTest.java index eeb71d8215..8a0074aa7b 100644 --- a/jOOQ/src/test/java/org/jooq/test/jOOQTest.java +++ b/jOOQ/src/test/java/org/jooq/test/jOOQTest.java @@ -1884,6 +1884,11 @@ public class jOOQTest { SelectQuery q = create.selectQuery(); q.addFrom(TABLE1); + q.addGroupBy(); + assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\" group by ()", r_refI().render(q)); + assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\" group by ()", r_ref().render(q)); + assertEquals(q, create.select().from(TABLE1).groupBy()); + q.addGroupBy(FIELD_ID1); assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\" group by \"TABLE1\".\"ID1\"", r_refI().render(q)); assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\" group by \"TABLE1\".\"ID1\"", r_ref().render(q));