[#1665] Add support for the empty GROUP BY () clause

This commit is contained in:
Lukas Eder 2012-08-05 23:00:06 +02:00
parent c1fb5a373e
commit c0be23d7c5
7 changed files with 61 additions and 5 deletions

View File

@ -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<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
@Test
public void testGrouping() throws Exception {
// [#1665] Test the empty GROUP BY clause
assertEquals(1, (int) create().selectOne()
.from(TBook())
.groupBy()
.fetchOne(0, Integer.class));
// [#1665] Test the empty GROUP BY clause
assertEquals(1, (int) create().selectOne()
.from(TBook())
.groupBy()
.having(trueCondition())
.fetchOne(0, Integer.class));
// Test a simple group by query
Field<Integer> count = count().as("c");
Result<Record> result = create()

View File

@ -1341,6 +1341,20 @@ GROUP BY AUTHOR_ID]]></sql>
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.
</p>
<h3>Empty GROUP BY clauses</h3>
<p>
jOOQ supports empty <code>GROUP BY ()</code> clauses as well. This will result in <reference id="select-statement" title="SELECT statements"/> that return only one record.
</p>
<code-pair>
<sql><![CDATA[SELECT COUNT(*)
FROM BOOK
GROUP BY ()]]></sql>
<java><![CDATA[create.selectCount()
.from(BOOK)
.groupBy();]]></java></code-pair>
<h3>ROLLUP(), CUBE() and GROUPING SETS()</h3>
<p>
Some databases support the SQL standard grouping functions and some extensions thereof. See the manual's section about <reference id="grouping-functions" title="grouping functions"/> for more details.

View File

@ -83,12 +83,18 @@ public interface SelectGroupByStep extends SelectHavingStep {
/**
* Add a <code>GROUP BY</code> clause to the query
* <p>
* Calling this with an empty argument list will result in an empty
* <code>GROUP BY ()</code> clause being rendered.
*/
@Support
SelectHavingStep groupBy(Field<?>... fields);
/**
* Add a <code>GROUP BY</code> clause to the query
* <p>
* Calling this with an empty argument list will result in an empty
* <code>GROUP BY ()</code> clause being rendered.
*/
@Support
SelectHavingStep groupBy(Collection<? extends Field<?>> fields);

View File

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

View File

@ -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;
}

View File

@ -105,6 +105,7 @@ class SelectQueryImpl extends AbstractSubSelect<Record> implements SelectQuery {
@Override
public final void addGroupBy(Collection<? extends Field<?>> fields) {
setGrouping();
getGroupBy().addAll(fields);
}

View File

@ -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));