[jOOQ/jOOQ#12910] Add DSL.emptyGroupingSet(): GroupField for explicit
empty grouping sets This also fixes: - [jOOQ/jOOQ#12908] Select:: loses GROUP BY clause
This commit is contained in:
parent
3009752b64
commit
0e9a2abeca
@ -65,6 +65,14 @@ import org.jooq.impl.QOM;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public /* sealed */ interface GroupField extends QueryPart /* permits Table, Field, QOM.Rollup, QOM.Cube, QOM.GroupingSets */ {
|
||||
|
||||
}
|
||||
public /* sealed */ interface GroupField
|
||||
extends
|
||||
QueryPart
|
||||
/* permits
|
||||
Table,
|
||||
Field,
|
||||
QOM.EmptyGroupingSet,
|
||||
QOM.Rollup,
|
||||
QOM.Cube,
|
||||
QOM.GroupingSets */
|
||||
{}
|
||||
|
||||
@ -24265,6 +24265,26 @@ public class DSL {
|
||||
// XXX Construction of GROUPING SET functions
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a GROUPING SETS(field1, field2, .., fieldn) grouping field where
|
||||
* each grouping set only consists of a single field.
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
* href="http://msdn.microsoft.com/en-US/library/bb522495.aspx"
|
||||
* >http://msdn.microsoft.com/en-US/library/bb522495.aspx</a>
|
||||
*
|
||||
* @param fields The fields that are part of the <code>GROUPING SETS</code>
|
||||
* function
|
||||
* @return A field to be used in a <code>GROUP BY</code> clause
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ POSTGRES })
|
||||
public static GroupField emptyGroupingSet() {
|
||||
return EmptyGroupingSet.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ROLLUP(field1, field2, .., fieldn) grouping field.
|
||||
*
|
||||
@ -24279,16 +24299,6 @@ public class DSL {
|
||||
/**
|
||||
* Create a ROLLUP(field1, field2, .., fieldn) grouping field.
|
||||
* <p>
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>MySQL (emulated using the GROUP BY .. WITH ROLLUP clause)</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>PostgreSQL 9.5</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
@ -24319,15 +24329,6 @@ public class DSL {
|
||||
/**
|
||||
* Create a CUBE(field1, field2, .., fieldn) grouping field.
|
||||
* <p>
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>PostgreSQL 9.5</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
@ -24348,15 +24349,6 @@ public class DSL {
|
||||
* Create a GROUPING SETS(field1, field2, .., fieldn) grouping field where
|
||||
* each grouping set only consists of a single field.
|
||||
* <p>
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>PostgreSQL 9.5</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
@ -24378,15 +24370,6 @@ public class DSL {
|
||||
* Create a GROUPING SETS((field1a, field1b), (field2a), .., (fieldna,
|
||||
* fieldnb)) grouping field.
|
||||
* <p>
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>PostgreSQL 9.5</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
@ -24408,15 +24391,6 @@ public class DSL {
|
||||
* Create a GROUPING SETS((field1a, field1b), (field2a), .., (fieldna,
|
||||
* fieldnb)) grouping field.
|
||||
* <p>
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>PostgreSQL 9.5</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Please check the SQL Server documentation for a very nice explanation of
|
||||
* <code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code>
|
||||
* clauses in grouping contexts: <a
|
||||
|
||||
@ -40,6 +40,7 @@ package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
import static org.jooq.impl.DSL.emptyGroupingSet;
|
||||
import static org.jooq.impl.DSL.groupingSets;
|
||||
import static org.jooq.impl.DSL.one;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
@ -128,7 +129,7 @@ final class GroupFieldList extends QueryPartList<GroupField> {
|
||||
|
||||
// Few dialects support the SQL standard "grand total" (i.e. empty grouping set)
|
||||
else
|
||||
ctx.sql("()");
|
||||
ctx.visit(emptyGroupingSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -526,6 +526,14 @@ public final class QOM {
|
||||
// XXX: SelectFields, GroupFields and SortFields
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public /* sealed */ interface EmptyGroupingSet
|
||||
extends
|
||||
GroupField,
|
||||
UEmpty
|
||||
/* permits
|
||||
org.jooq.impl.EmptyGroupingSet */
|
||||
{}
|
||||
|
||||
// Can't seal these types yet because of https://bugs.eclipse.org/bugs/show_bug.cgi?id=577872
|
||||
|
||||
public /* non-sealed */ interface Rollup
|
||||
|
||||
@ -121,6 +121,7 @@ import static org.jooq.impl.CombineOperator.UNION_ALL;
|
||||
import static org.jooq.impl.CommonTableExpressionList.markTopLevelCteAndAccept;
|
||||
import static org.jooq.impl.DSL.asterisk;
|
||||
import static org.jooq.impl.DSL.createTable;
|
||||
import static org.jooq.impl.DSL.emptyGroupingSet;
|
||||
import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.impl.DSL.generateSeries;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
@ -366,8 +367,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
private final TableList from;
|
||||
private final ConditionProviderImpl condition;
|
||||
private boolean grouping;
|
||||
private GroupFieldList groupBy;
|
||||
private final GroupFieldList groupBy;
|
||||
private boolean groupByDistinct;
|
||||
private final ConditionProviderImpl having;
|
||||
private WindowList window;
|
||||
@ -416,6 +416,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
|
||||
|
||||
this.groupBy = new GroupFieldList();
|
||||
this.having = new ConditionProviderImpl();
|
||||
this.qualify = new ConditionProviderImpl();
|
||||
this.orderBy = new SortFieldList();
|
||||
@ -504,7 +505,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private final SelectQueryImpl<R> copyTo(CopyClause clause, boolean scalarSelect, SelectQueryImpl<R> result) {
|
||||
@ -531,8 +531,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
|
||||
|
||||
result.grouping = grouping;
|
||||
result.groupBy = groupBy;
|
||||
result.groupBy.addAll(groupBy);
|
||||
result.groupByDistinct = groupByDistinct;
|
||||
result.having.setWhere(having.getWhere());
|
||||
if (window != null)
|
||||
@ -2380,7 +2379,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
// --------------------------
|
||||
context.start(SELECT_GROUP_BY);
|
||||
|
||||
if (grouping) {
|
||||
if (!getGroupBy().isEmpty()) {
|
||||
context.formatSeparator()
|
||||
.visit(K_GROUP_BY);
|
||||
|
||||
@ -3800,13 +3799,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
return from;
|
||||
}
|
||||
|
||||
final void setGrouping() {
|
||||
grouping = true;
|
||||
|
||||
if (groupBy == null)
|
||||
groupBy = new GroupFieldList();
|
||||
}
|
||||
|
||||
final ConditionProviderImpl getWhere(Context<?> ctx) {
|
||||
ConditionProviderImpl result = new ConditionProviderImpl();
|
||||
|
||||
@ -3890,6 +3882,10 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
|
||||
|
||||
final GroupFieldList getGroupBy() {
|
||||
return groupBy;
|
||||
}
|
||||
|
||||
final ConditionProviderImpl getHaving() {
|
||||
return having;
|
||||
}
|
||||
@ -4099,13 +4095,18 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
@Override
|
||||
public final void addGroupBy(Collection<? extends GroupField> fields) {
|
||||
setGrouping();
|
||||
|
||||
// [#12910] For backwards compatibility, adding empty GROUP BY lists to
|
||||
// a blank GROUP BY clause must maintain empty grouping set
|
||||
// semantics
|
||||
if (fields.isEmpty())
|
||||
groupBy.add(emptyGroupingSet());
|
||||
|
||||
groupBy.addAll(fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setGroupByDistinct(boolean groupByDistinct) {
|
||||
setGrouping();
|
||||
this.groupByDistinct = groupByDistinct;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user