From 042c34a19d778d5c847129a5bc48116244a1fc5b Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 24 Jan 2022 12:00:00 +0100 Subject: [PATCH] [jOOQ/jOOQ#12910] Fix empty grouping emulations for various dialects --- jOOQ/src/main/java/org/jooq/impl/DSL.java | 2 +- .../java/org/jooq/impl/EmptyGroupingSet.java | 78 +++++++++++++++++++ .../java/org/jooq/impl/GroupFieldList.java | 77 ++++++------------ 3 files changed, 102 insertions(+), 55 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index dd97aac36e..1742e06fb7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -24280,7 +24280,7 @@ public class DSL { * @return A field to be used in a GROUP BY clause */ @NotNull - @Support({ POSTGRES }) + @Support public static GroupField emptyGroupingSet() { return EmptyGroupingSet.INSTANCE; } diff --git a/jOOQ/src/main/java/org/jooq/impl/EmptyGroupingSet.java b/jOOQ/src/main/java/org/jooq/impl/EmptyGroupingSet.java index 93a4766528..de66e3bf5e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/EmptyGroupingSet.java +++ b/jOOQ/src/main/java/org/jooq/impl/EmptyGroupingSet.java @@ -37,15 +37,65 @@ */ package org.jooq.impl; +import static java.util.Arrays.asList; +// ... +// ... +// ... +// ... +// ... +import static org.jooq.SQLDialect.CUBRID; +import static org.jooq.SQLDialect.DERBY; +import static org.jooq.SQLDialect.FIREBIRD; +// ... +import static org.jooq.SQLDialect.HSQLDB; +import static org.jooq.SQLDialect.IGNITE; +// ... +// ... +import static org.jooq.SQLDialect.MARIADB; +// ... +import static org.jooq.SQLDialect.MYSQL; +import static org.jooq.SQLDialect.POSTGRES; +// ... +// ... +// ... +import static org.jooq.SQLDialect.SQLITE; +// ... +import static org.jooq.SQLDialect.YUGABYTEDB; +import static org.jooq.impl.DSL.groupingSets; +import static org.jooq.impl.DSL.one; import static org.jooq.impl.SQLDataType.OTHER; +import static org.jooq.impl.Tools.EMPTY_FIELD; + +import java.util.EnumSet; +import java.util.Set; import org.jooq.Context; +// ... +import org.jooq.SQLDialect; /** * @author Lukas Eder */ final class EmptyGroupingSet extends AbstractField implements QOM.EmptyGroupingSet { + static final Set EMULATE_EMPTY_GROUP_BY_CONSTANT = SQLDialect.supportedUntil(DERBY, HSQLDB, IGNITE); + static final Set EMULATE_EMPTY_GROUP_BY_OTHER = SQLDialect.supportedUntil(FIREBIRD, MARIADB, MYSQL, SQLITE, YUGABYTEDB); + + + + + + + + + + + + + + + + static final EmptyGroupingSet INSTANCE = new EmptyGroupingSet(); private EmptyGroupingSet() { @@ -54,6 +104,34 @@ final class EmptyGroupingSet extends AbstractField implements QOM.EmptyG @Override public final void accept(Context ctx) { + + // [#4292] Some dialects accept constant expressions in GROUP BY + // Note that dialects may consider constants as indexed field + // references, as in the ORDER BY clause! + if (EMULATE_EMPTY_GROUP_BY_CONSTANT.contains(ctx.dialect())) + ctx.sql('0'); + + // [#4447] CUBRID can't handle subqueries in GROUP BY + else if (ctx.family() == CUBRID) + ctx.sql("1 + 0"); + + + + + + + + + + + + // [#4292] Some dialects don't support empty GROUP BY () clauses + else if (EMULATE_EMPTY_GROUP_BY_OTHER.contains(ctx.dialect())) + ctx.sql('(').visit(DSL.select(one())).sql(')'); + + // Few dialects support the SQL standard "grand total" (i.e. empty grouping set) + else + ctx.sql("()"); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/GroupFieldList.java b/jOOQ/src/main/java/org/jooq/impl/GroupFieldList.java index 17e9928d8f..1bdc132282 100644 --- a/jOOQ/src/main/java/org/jooq/impl/GroupFieldList.java +++ b/jOOQ/src/main/java/org/jooq/impl/GroupFieldList.java @@ -38,20 +38,35 @@ package org.jooq.impl; -import static java.util.Arrays.asList; -import static org.jooq.SQLDialect.*; +// ... +// ... +// ... +// ... +import static org.jooq.SQLDialect.DERBY; +// ... +import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.H2; +// ... +import static org.jooq.SQLDialect.HSQLDB; +// ... +import static org.jooq.SQLDialect.MARIADB; +// ... +import static org.jooq.SQLDialect.MYSQL; +// ... +import static org.jooq.SQLDialect.POSTGRES; +// ... +// ... +import static org.jooq.SQLDialect.SQLITE; +// ... +// ... +import static org.jooq.SQLDialect.YUGABYTEDB; 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; -import java.util.EnumSet; import java.util.Set; import org.jooq.Context; import org.jooq.Field; import org.jooq.GroupField; -// ... import org.jooq.SQLDialect; import org.jooq.Table; import org.jooq.UniqueKey; @@ -61,25 +76,9 @@ import org.jooq.UniqueKey; */ final class GroupFieldList extends QueryPartList { - static final Set EMULATE_EMPTY_GROUP_BY_CONSTANT = SQLDialect.supportedUntil(DERBY, HSQLDB, IGNITE); - static final Set EMULATE_EMPTY_GROUP_BY_OTHER = SQLDialect.supportedUntil(FIREBIRD, MARIADB, MYSQL, SQLITE, YUGABYTEDB); static final Set NO_SUPPORT_GROUP_BY_TABLE = SQLDialect.supportedBy(DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB); static final Set NO_SUPPORT_GROUP_FUNCTIONAL_DEP = SQLDialect.supportedBy(DERBY, FIREBIRD); - - - - - - - - - - - - - - GroupFieldList() { super(); } @@ -99,37 +98,7 @@ final class GroupFieldList extends QueryPartList { @Override protected final void toSQLEmptyList(Context ctx) { - // [#1665] Empty GROUP BY () clauses need parentheses - - ctx.sql(' '); - - // [#4292] Some dialects accept constant expressions in GROUP BY - // Note that dialects may consider constants as indexed field - // references, as in the ORDER BY clause! - if (EMULATE_EMPTY_GROUP_BY_CONSTANT.contains(ctx.dialect())) - ctx.sql('0'); - - // [#4447] CUBRID can't handle subqueries in GROUP BY - else if (ctx.family() == CUBRID) - ctx.sql("1 + 0"); - - - - - - - - - - - - // [#4292] Some dialects don't support empty GROUP BY () clauses - else if (EMULATE_EMPTY_GROUP_BY_OTHER.contains(ctx.dialect())) - ctx.sql('(').visit(DSL.select(one())).sql(')'); - - // Few dialects support the SQL standard "grand total" (i.e. empty grouping set) - else - ctx.visit(emptyGroupingSet()); + ctx.sql(' ').visit(emptyGroupingSet()); } @Override