From df90a78f71862dbb8443e17830ca880a0b0e8140 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 19 Feb 2021 16:45:38 +0100 Subject: [PATCH] [jOOQ/jOOQ#11238] Fixed MariaDB and MySQL emulations --- .../jooq/impl/AbstractAggregateFunction.java | 42 +++++++++---------- .../main/java/org/jooq/impl/JSONArrayAgg.java | 13 ++++-- .../java/org/jooq/impl/JSONObjectAgg.java | 23 ++++++---- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java index 5c252c63a6..094a7b2965 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java @@ -84,21 +84,21 @@ implements /** * Generated UID */ - private static final long serialVersionUID = -8613744948308064895L; - private static final Set SUPPORT_FILTER = SQLDialect.supportedBy(H2, HSQLDB, POSTGRES, SQLITE); - private static final Set SUPPORT_DISTINCT_RVE = SQLDialect.supportedBy(H2, POSTGRES); + private static final long serialVersionUID = -8613744948308064895L; + static final Set SUPPORT_FILTER = SQLDialect.supportedBy(H2, HSQLDB, POSTGRES, SQLITE); + static final Set SUPPORT_DISTINCT_RVE = SQLDialect.supportedBy(H2, POSTGRES); - static final Field ASTERISK = DSL.field("*", Integer.class); + static final Field ASTERISK = DSL.field("*", Integer.class); // Other attributes - final QueryPartList> arguments; - final boolean distinct; - Condition filter; + final QueryPartList> arguments; + final boolean distinct; + Condition filter; // Other attributes - SortFieldList withinGroupOrderBy; - SortFieldList keepDenseRankOrderBy; - boolean first; + SortFieldList withinGroupOrderBy; + SortFieldList keepDenseRankOrderBy; + boolean first; AbstractAggregateFunction(boolean distinct, Name name, DataType type, Field... arguments) { super(name, type); @@ -124,25 +124,21 @@ implements ctx.sql('('); } - if (!args.isEmpty()) { - if (filter == null || SUPPORT_FILTER.contains(ctx.dialect())) { - ctx.visit(args); - } - else { - QueryPartList> expressions = new QueryPartList<>(); - - for (Field argument : args) - expressions.add(DSL.when(filter, argument == ASTERISK ? one() : argument)); - - ctx.visit(expressions); - } - } + if (!args.isEmpty()) + acceptArguments2(ctx, args); if (distinct) if (args.size() > 1 && SUPPORT_DISTINCT_RVE.contains(ctx.dialect())) ctx.sql(')'); } + final void acceptArguments2(Context ctx, QueryPartCollectionView> args) { + if (filter == null || SUPPORT_FILTER.contains(ctx.dialect())) + ctx.visit(args); + else + ctx.visit(args.map(arg -> DSL.when(filter, arg == ASTERISK ? one() : arg))); + } + final void acceptFilterClause(Context ctx) { acceptFilterClause(ctx, filter); } diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java b/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java index 88cd4a789c..f84fe21b89 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java @@ -47,6 +47,7 @@ import static org.jooq.impl.DSL.noCondition; import static org.jooq.impl.JSONEntryImpl.jsonCast; import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL; import static org.jooq.impl.JSONOnNull.NULL_ON_NULL; +import static org.jooq.impl.Names.N_GROUP_CONCAT; import static org.jooq.impl.Names.N_JSONB_AGG; import static org.jooq.impl.Names.N_JSON_AGG; import static org.jooq.impl.Names.N_JSON_ARRAYAGG; @@ -156,10 +157,14 @@ implements JSONArrayAggOrderByStep { Field arg2 = arg1; return DSL.concat( inline('['), - DSL.field("{0}", VARCHAR, CustomQueryPart.of(c -> { - c.visit(groupConcatEmulationWithoutArrayWrappers(arg2, withinGroupOrderBy)); - acceptOverClause(c); - })), + CustomField.of(N_GROUP_CONCAT, VARCHAR, c1 -> { + c1.visit(groupConcatEmulationWithoutArrayWrappers( + CustomField.of(Names.N_FIELD, VARCHAR, c2 -> acceptArguments2(c2, QueryPartListView.wrap(arg2))), + withinGroupOrderBy + )); + acceptFilterClause(ctx); + acceptOverClause(c1); + }), inline(']') ); } diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONObjectAgg.java b/jOOQ/src/main/java/org/jooq/impl/JSONObjectAgg.java index 4c24b34ff9..89d14ab6e1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONObjectAgg.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONObjectAgg.java @@ -46,6 +46,7 @@ import static org.jooq.impl.DSL.noCondition; import static org.jooq.impl.DSL.when; import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL; import static org.jooq.impl.JSONOnNull.NULL_ON_NULL; +import static org.jooq.impl.Names.N_FIELD; import static org.jooq.impl.Names.N_JSONB_OBJECT_AGG; import static org.jooq.impl.Names.N_JSON_OBJECTAGG; import static org.jooq.impl.Names.N_JSON_OBJECT_AGG; @@ -106,7 +107,9 @@ implements JSONObjectAggNullStep { // [#10089] These dialects support non-standard JSON_OBJECTAGG without ABSENT ON NULL support case MARIADB: case MYSQL: - if (onNull == ABSENT_ON_NULL) + + // [#11238] FILTER cannot be emulated with the standard syntax + if (onNull == ABSENT_ON_NULL || filter != null) acceptGroupConcat(ctx); @@ -137,17 +140,21 @@ implements JSONObjectAggNullStep { } private final void acceptGroupConcat(Context ctx) { - final Field listagg = DSL.field("{0}", String.class, CustomQueryPart.of(c -> { - Field o = jsonObject(entry.key(), entry.value()); + final Field listagg = CustomField.of(Names.N_GROUP_CONCAT, VARCHAR, c1 -> { + Field o1 = jsonObject(entry.key(), entry.value()); if (onNull == ABSENT_ON_NULL) - o = when(entry.value().isNull(), inline((JSON) null)).else_(o); + o1 = when(entry.value().isNull(), inline((JSON) null)).else_(o1); - c.visit(groupConcat(DSL.concat( - DSL.regexpReplaceAll(o.cast(VARCHAR), inline("^\\{(.*)\\}$"), inline(RegexpReplace.replacement(ctx, 1))) + Field o2 = o1; + c1.visit(groupConcat(DSL.concat( + CustomField.of(N_FIELD, VARCHAR, c2 -> acceptArguments2(c2, QueryPartListView.wrap( + DSL.regexpReplaceAll(o2.cast(VARCHAR), inline("^\\{(.*)\\}$"), inline(RegexpReplace.replacement(ctx, 1))) + ))) ))); - acceptOverClause(c); - })); + + acceptOverClause(c1); + }); ctx.sql('(').visit(DSL.concat(inline('{'), listagg, inline('}'))).sql(')'); }