From 8a0766e8880b27fab7d950d6851d38f99c344ffe Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 21 May 2020 12:31:40 +0200 Subject: [PATCH] [jOOQ/jOOQ#10153] Emulate GROUP BY () in HANA using GROUPING SETS (()) --- jOOQ/src/main/java/org/jooq/impl/DSL.java | 6 ++-- .../src/main/java/org/jooq/impl/Keywords.java | 30 ++++++++++--------- .../java/org/jooq/impl/SelectQueryImpl.java | 5 ++++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 8fb8c4ed1d..26949424c2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -85,6 +85,8 @@ import static org.jooq.SQLDialect.SQLITE; // ... // ... // ... +import static org.jooq.impl.Keywords.K_CUBE; +import static org.jooq.impl.Keywords.K_GROUPING_SETS; import static org.jooq.impl.Names.N_IF; import static org.jooq.impl.Names.N_IIF; import static org.jooq.impl.Names.N_SYSTEM_TIME; @@ -17140,7 +17142,7 @@ public class DSL { */ @Support({ POSTGRES }) public static GroupField cube(FieldOrRow... fields) { - return field("{cube}({0})", Object.class, new QueryPartList<>(fields)); + return field("{0} ({1})", Object.class, K_CUBE, new QueryPartList<>(fields)); } /** @@ -17239,7 +17241,7 @@ public class DSL { for (Collection> fieldsSet : fieldSets) arg.add(new WrappedList(new QueryPartList<>(fieldsSet))); - return field("grouping sets({0})", SQLDataType.OTHER, arg); + return field("{0} ({1})", SQLDataType.OTHER, K_GROUPING_SETS, arg); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Keywords.java b/jOOQ/src/main/java/org/jooq/impl/Keywords.java index f16d2b2958..436f322112 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Keywords.java +++ b/jOOQ/src/main/java/org/jooq/impl/Keywords.java @@ -52,8 +52,8 @@ final class Keywords { static final Keyword K_ADD = keyword("add"); static final Keyword K_AFTER = keyword("after"); static final Keyword K_ALIAS = keyword("alias"); - static final Keyword K_ALTER = keyword("alter"); static final Keyword K_ALL = keyword("all"); + static final Keyword K_ALTER = keyword("alter"); static final Keyword K_ALTER_COLUMN = keyword("alter column"); static final Keyword K_ALTER_CONSTRAINT = keyword("alter constraint"); static final Keyword K_ALTER_INDEX = keyword("alter index"); @@ -65,8 +65,8 @@ final class Keywords { static final Keyword K_AS_OF = keyword("as of"); static final Keyword K_ATOMIC = keyword("atomic"); static final Keyword K_AUTO = keyword("auto"); - static final Keyword K_AUTO_INCREMENT = keyword("auto_increment"); static final Keyword K_AUTOINCREMENT = keyword("autoincrement"); + static final Keyword K_AUTO_INCREMENT = keyword("auto_increment"); static final Keyword K_BEFORE = keyword("before"); static final Keyword K_BEGIN = keyword("begin"); static final Keyword K_BEGIN_CATCH = keyword("begin catch"); @@ -103,6 +103,7 @@ final class Keywords { static final Keyword K_CONTINUE_IDENTITY = keyword("continue identity"); static final Keyword K_CREATE = keyword("create"); static final Keyword K_CROSS_JOIN_LATERAL = keyword("cross join lateral"); + static final Keyword K_CUBE = keyword("cube"); static final Keyword K_CURRENT = keyword("current"); static final Keyword K_CURRENT_ROW = keyword("current row"); static final Keyword K_CURRENT_SCHEMA = keyword("current_schema"); @@ -128,9 +129,9 @@ final class Keywords { static final Keyword K_DISTINCT = keyword("distinct"); static final Keyword K_DISTINCT_ON = keyword("distinct on"); static final Keyword K_DO = keyword("do"); + static final Keyword K_DOCUMENT = keyword("document"); static final Keyword K_DO_NOTHING = keyword("do nothing"); static final Keyword K_DO_UPDATE = keyword("do update"); - static final Keyword K_DOCUMENT = keyword("document"); static final Keyword K_DROP = keyword("drop"); static final Keyword K_DROP_COLUMN = keyword("drop column"); static final Keyword K_DROP_CONSTRAINT = keyword("drop constraint"); @@ -173,12 +174,12 @@ final class Keywords { static final Keyword K_FIRST = keyword("first"); static final Keyword K_FOLLOWING = keyword("following"); static final Keyword K_FOR = keyword("for"); - static final Keyword K_FOR_PORTION_OF = keyword("for portion of"); - static final Keyword K_FOR_SHARE = keyword("for share"); - static final Keyword K_FOR_UPDATE = keyword("for update"); static final Keyword K_FORALL = keyword("forall"); static final Keyword K_FOREIGN_KEY = keyword("foreign key"); static final Keyword K_FORMAT = keyword("format"); + static final Keyword K_FOR_PORTION_OF = keyword("for portion of"); + static final Keyword K_FOR_SHARE = keyword("for share"); + static final Keyword K_FOR_UPDATE = keyword("for update"); static final Keyword K_FROM = keyword("from"); static final Keyword K_FUNCTION = keyword("function"); static final Keyword K_GENERATED_BY_DEFAULT_AS_IDENTITY = keyword("generated by default as identity"); @@ -186,6 +187,7 @@ final class Keywords { static final Keyword K_GOTO = keyword("goto"); static final Keyword K_GRANT = keyword("grant"); static final Keyword K_GRANT_OPTION_FOR = keyword("grant option for"); + static final Keyword K_GROUPING_SETS = keyword("grouping sets"); static final Keyword K_GROUP_BY = keyword("group by"); static final Keyword K_HAVING = keyword("having"); static final Keyword K_HOUR = keyword("hour"); @@ -209,17 +211,17 @@ final class Keywords { static final Keyword K_INTO = keyword("into"); static final Keyword K_IS = keyword("is"); static final Keyword K_IS_DOCUMENT = keyword("is document"); + static final Keyword K_IS_JSON = keyword("is json"); static final Keyword K_IS_NOT_DOCUMENT = keyword("is not document"); static final Keyword K_IS_NOT_JSON = keyword("is not json"); static final Keyword K_IS_NOT_NULL = keyword("is not null"); - static final Keyword K_IS_JSON = keyword("is json"); static final Keyword K_IS_NULL = keyword("is null"); static final Keyword K_ITERATE = keyword("iterate"); static final Keyword K_JSON = keyword("json"); static final Keyword K_JSON_ARRAY = keyword("json_array"); static final Keyword K_JSON_EXISTS = keyword("json_exists"); - static final Keyword K_JSON_TABLE = keyword("json_table"); static final Keyword K_JSON_OBJECT = keyword("json_object"); + static final Keyword K_JSON_TABLE = keyword("json_table"); static final Keyword K_KEEP = keyword("keep"); static final Keyword K_KEY = keyword("key"); static final Keyword K_KEYS = keyword("keys"); @@ -247,8 +249,8 @@ final class Keywords { static final Keyword K_MULTISET = keyword("multiset"); static final Keyword K_NAME = keyword("name"); static final Keyword K_NEW_TABLE = keyword("new table"); - static final Keyword K_NEXT_VALUE_FOR = keyword("next value for"); static final Keyword K_NEXTVAL = keyword("nextval"); + static final Keyword K_NEXT_VALUE_FOR = keyword("next value for"); static final Keyword K_NO = keyword("no"); static final Keyword K_NOCYCLE = keyword("nocycle"); static final Keyword K_NONCLUSTERED = keyword("nonclustered"); @@ -300,6 +302,7 @@ final class Keywords { static final Keyword K_QUALIFY = keyword("qualify"); static final Keyword K_RAISE = keyword("raise"); static final Keyword K_RAISERROR = keyword("raiserror"); + static final Keyword K_RAW = keyword("raw"); static final Keyword K_READPAST = keyword("readpast"); static final Keyword K_RECORD = keyword("record"); static final Keyword K_RECURSIVE = keyword("recursive"); @@ -325,7 +328,6 @@ final class Keywords { static final Keyword K_RETURNING = keyword("returning"); static final Keyword K_REVERSE = keyword("reverse"); static final Keyword K_REVOKE = keyword("revoke"); - static final Keyword K_RAW = keyword("raw"); static final Keyword K_ROOT = keyword("root"); static final Keyword K_ROW = keyword("row"); static final Keyword K_ROWCOUNT = keyword("rowcount"); @@ -363,9 +365,9 @@ final class Keywords { static final Keyword K_THEN = keyword("then"); static final Keyword K_THROW = keyword("throw"); static final Keyword K_TIME = keyword("time"); - static final Keyword K_TIME_WITH_TIME_ZONE = keyword("time with time zone"); static final Keyword K_TIMESTAMP = keyword("timestamp"); static final Keyword K_TIMESTAMP_WITH_TIME_ZONE = keyword("timestamp with time zone"); + static final Keyword K_TIME_WITH_TIME_ZONE = keyword("time with time zone"); static final Keyword K_TO = keyword("to"); static final Keyword K_TOP = keyword("top"); static final Keyword K_TRAILING = keyword("trailing"); @@ -394,6 +396,8 @@ final class Keywords { static final Keyword K_WHILE = keyword("while"); static final Keyword K_WINDOW = keyword("window"); static final Keyword K_WITH = keyword("with"); + static final Keyword K_WITHIN_GROUP = keyword("within group"); + static final Keyword K_WITHOUT_ARRAY_WRAPPER = keyword("without_array_wrapper"); static final Keyword K_WITH_CHECK_OPTION = keyword("with check option"); static final Keyword K_WITH_DATA = keyword("with data"); static final Keyword K_WITH_GRANT_OPTION = keyword("with grant option"); @@ -404,16 +408,14 @@ final class Keywords { static final Keyword K_WITH_READ_ONLY = keyword("with read only"); static final Keyword K_WITH_ROLLUP = keyword("with rollup"); static final Keyword K_WITH_TIES = keyword("with ties"); - static final Keyword K_WITHIN_GROUP = keyword("within group"); - static final Keyword K_WITHOUT_ARRAY_WRAPPER = keyword("without_array_wrapper"); static final Keyword K_XML = keyword("xml"); static final Keyword K_XMLEXISTS = keyword("xmlexists"); static final Keyword K_XMLTABLE = keyword("xmltable"); static final Keyword K_YEAR = keyword("year"); static final Keyword K_YEAR_MONTH = keyword("year_month"); static final Keyword K_YEAR_TO_DAY = keyword("year to day"); - static final Keyword K_YEAR_TO_MONTH = keyword("year to month"); static final Keyword K_YEAR_TO_FRACTION = keyword("year to fraction"); + static final Keyword K_YEAR_TO_MONTH = keyword("year to month"); private Keywords() {} } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 8698eb1cac..98cac271d4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -99,6 +99,7 @@ import static org.jooq.impl.CombineOperator.UNION; import static org.jooq.impl.CombineOperator.UNION_ALL; import static org.jooq.impl.DSL.asterisk; import static org.jooq.impl.DSL.falseCondition; +import static org.jooq.impl.DSL.groupingSets; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.jsonArrayAgg; import static org.jooq.impl.DSL.jsonEntry; @@ -1760,6 +1761,10 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + + + // [#4292] Some dialects don't support empty GROUP BY () clauses else if (EMULATE_EMPTY_GROUP_BY_OTHER.contains(family)) context.sql('(').visit(DSL.select(one())).sql(')');