From 47da07933215b21231d672af036e539ce66394cc Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 30 Jun 2021 11:19:53 +0200 Subject: [PATCH] [jOOQ/jOOQ#12085] Work around Oracle's JSON_ARRAYAGG() bugs when aggregate inputs should be DISTINCT --- .../main/java/org/jooq/impl/JSONArrayAgg.java | 22 ++++++++++++++++++- .../src/main/java/org/jooq/impl/Multiset.java | 13 +++++++++-- .../java/org/jooq/impl/SelectQueryImpl.java | 8 ++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java b/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java index f0ef4df13d..4096e531cc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONArrayAgg.java @@ -42,11 +42,11 @@ import static org.jooq.SQLDialect.MARIADB; // ... import static org.jooq.SQLDialect.MYSQL; // ... +// ... import static org.jooq.impl.DSL.function; import static org.jooq.impl.DSL.groupConcat; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.noCondition; -import static org.jooq.impl.JSONEntryImpl.jsonCast; import static org.jooq.impl.JSONEntryImpl.jsonCastMapper; import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL; import static org.jooq.impl.JSONOnNull.NULL_ON_NULL; @@ -64,13 +64,17 @@ import static org.jooq.impl.Tools.BooleanDataKey.DATA_FORCE_CASE_ELSE_NULL; import java.util.Collection; import java.util.Set; +import org.jooq.Configuration; import org.jooq.Context; import org.jooq.DataType; import org.jooq.Field; import org.jooq.JSONArrayAggOrderByStep; import org.jooq.OrderField; // ... +import org.jooq.Record; import org.jooq.SQLDialect; +import org.jooq.Select; +import org.jooq.SelectHavingStep; /** @@ -81,9 +85,14 @@ import org.jooq.SQLDialect; final class JSONArrayAgg extends AbstractAggregateFunction implements JSONArrayAggOrderByStep { + static final Set EMULATE_WITH_GROUP_CONCAT = SQLDialect.supportedBy(MARIADB, MYSQL); static final Set SUPPORT_JSON_MERGE_PRESERVE = SQLDialect.supportedBy(MARIADB, MYSQL); + + + + private JSONOnNull onNull; private DataType returning; @@ -250,4 +259,15 @@ implements JSONArrayAggOrderByStep { public final JSONArrayAgg orderBy(Collection> fields) { return (JSONArrayAgg) super.orderBy(fields); } + + static final Select patchOracleArrayAggBug(Configuration configuration, SelectHavingStep select) { + + + + + + + + return select; + } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Multiset.java b/jOOQ/src/main/java/org/jooq/impl/Multiset.java index 9c43b1df7e..02f8275418 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Multiset.java +++ b/jOOQ/src/main/java/org/jooq/impl/Multiset.java @@ -54,6 +54,7 @@ import static org.jooq.impl.DSL.selectFrom; import static org.jooq.impl.DSL.xmlagg; import static org.jooq.impl.DSL.xmlelement; import static org.jooq.impl.DSL.xmlserializeContent; +import static org.jooq.impl.JSONArrayAgg.patchOracleArrayAggBug; import static org.jooq.impl.Keywords.K_MULTISET; import static org.jooq.impl.Names.N_MULTISET; import static org.jooq.impl.Names.N_RECORD; @@ -147,7 +148,11 @@ final class Multiset extends AbstractField> { if (multisetCondition) filter = order.orderBy(t.fields()); - Select> s = select(DSL.coalesce(filter, jsonArray())).from(t); + Select> s = patchOracleArrayAggBug( + ctx.configuration(), + select(DSL.coalesce(filter, jsonArray())).from(t) + ); + if (multisetCondition && NO_SUPPORT_JSON_COMPARE.contains(ctx.dialect())) ctx.visit(DSL.field(s).cast(VARCHAR)); else @@ -183,7 +188,11 @@ final class Multiset extends AbstractField> { if (multisetCondition) filter = order.orderBy(t.fields()); - Select> s = select(DSL.coalesce(filter, jsonbArray())).from(t); + Select> s = patchOracleArrayAggBug( + ctx.configuration(), + select(DSL.coalesce(filter, jsonbArray())).from(t) + ); + visitSubquery(ctx, s, true); break; } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 9bdafb2876..ced1ced171 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -147,6 +147,7 @@ import static org.jooq.impl.DSL.xmlattributes; import static org.jooq.impl.DSL.xmlelement; import static org.jooq.impl.Internal.isub; import static org.jooq.impl.JSONArrayAgg.EMULATE_WITH_GROUP_CONCAT; +import static org.jooq.impl.JSONArrayAgg.patchOracleArrayAggBug; import static org.jooq.impl.JSONNull.NO_SUPPORT_ABSENT_ON_NULL; import static org.jooq.impl.Keywords.K_AND; import static org.jooq.impl.Keywords.K_BY; @@ -269,6 +270,7 @@ import org.jooq.SQLDialect; import org.jooq.Select; import org.jooq.SelectField; import org.jooq.SelectFieldOrAsterisk; +import org.jooq.SelectHavingStep; import org.jooq.SelectLimitPercentStep; import org.jooq.SelectLimitStep; import org.jooq.SelectOffsetStep; @@ -293,7 +295,6 @@ import org.jooq.impl.Tools.DataKey; import org.jooq.tools.JooqLogger; import org.jooq.tools.StringUtils; -import org.jetbrains.annotations.Nullable; /** * A sub-select is a SELECT statement that can be combined with @@ -1222,6 +1223,11 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + + + +