From 5b4a3b0cb25daddaf6e7c879cd24986e869732c5 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 14 Sep 2022 13:00:24 +0200 Subject: [PATCH] [jOOQ/jOOQ#12045] Simplified MULTISET emulation with DISTINCT Thanks to [jOOQ/jOOQ#10730], we can now also implement the simplified MULTISET emulation with subqueries containing the DISTINCT clause --- .../src/main/java/org/jooq/impl/Multiset.java | 23 +++++++++---------- .../main/java/org/jooq/impl/MultisetAgg.java | 4 ++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/Multiset.java b/jOOQ/src/main/java/org/jooq/impl/Multiset.java index 3ca9c12cfd..7e1cab39a2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Multiset.java +++ b/jOOQ/src/main/java/org/jooq/impl/Multiset.java @@ -188,13 +188,14 @@ final class Multiset extends AbstractField> implemen default: { if (NO_SUPPORT_CORRELATED_DERIVED_TABLE.contains(ctx.dialect()) && isSimple(select)) { JSONArrayAggReturningStep returning = - jsonArrayaggEmulation(ctx, row(map(select.getSelect(), f -> Tools.unalias(f))), true).orderBy(select.$orderBy()); + jsonArrayaggEmulation(ctx, row(map(select.getSelect(), f -> Tools.unalias(f))), true, select.$distinct()).orderBy(select.$orderBy()); Select s = select .$select(Arrays.asList(DSL.coalesce( returningClob(ctx, returning), returningClob(ctx, jsonArray()) ))) + .$distinct(false) .$orderBy(Arrays.asList()); visitSubquery(ctx, s); @@ -203,7 +204,7 @@ final class Multiset extends AbstractField> implemen JSONArrayAggOrderByStep order; JSONArrayAggReturningStep returning; - returning = order = jsonArrayaggEmulation(ctx, t, true); + returning = order = jsonArrayaggEmulation(ctx, t, true, false); // TODO: Re-apply derived table's ORDER BY clause as aggregate ORDER BY if (multisetCondition) @@ -254,13 +255,14 @@ final class Multiset extends AbstractField> implemen default: { if (NO_SUPPORT_CORRELATED_DERIVED_TABLE.contains(ctx.dialect()) && isSimple(select)) { JSONArrayAggReturningStep returning = - jsonbArrayaggEmulation(ctx, row(map(select.getSelect(), f -> Tools.unalias(f))), true).orderBy(select.$orderBy()); + jsonbArrayaggEmulation(ctx, row(map(select.getSelect(), f -> Tools.unalias(f))), true, select.$distinct()).orderBy(select.$orderBy()); Select s = select .$select(Arrays.asList(DSL.coalesce( returningClob(ctx, returning), returningClob(ctx, jsonArray()) ))) + .$distinct(false) .$orderBy(Arrays.asList()); visitSubquery(ctx, s); @@ -269,7 +271,7 @@ final class Multiset extends AbstractField> implemen JSONArrayAggOrderByStep order; JSONArrayAggReturningStep returning; - returning = order = jsonbArrayaggEmulation(ctx, t, false); + returning = order = jsonbArrayaggEmulation(ctx, t, false, false); // TODO: Re-apply derived table's ORDER BY clause as aggregate ORDER BY if (multisetCondition) @@ -320,7 +322,7 @@ final class Multiset extends AbstractField> implemen default: { - if (NO_SUPPORT_CORRELATED_DERIVED_TABLE.contains(ctx.dialect()) && isSimple(select)) { + if (NO_SUPPORT_CORRELATED_DERIVED_TABLE.contains(ctx.dialect()) && isSimple(select) && !select.$distinct()) { AggregateFilterStep filter = xmlaggEmulation(ctx, row(map(select.getSelect(), f -> Tools.unalias(f))), true).orderBy(select.$orderBy()); @@ -367,9 +369,6 @@ final class Multiset extends AbstractField> implemen && s.$having() == null && s.$window().isEmpty() && s.$qualify() == null - - // [#10730] [#12045] TODO: This could be supported - && !s.$distinct() && !selectQueryImpl(s).hasUnions() && s.$offset() == null && s.$limit() == null @@ -448,12 +447,12 @@ final class Multiset extends AbstractField> implemen // - It is column name agnostic (supporting ambiguous column names) // - The JSON never leaks outside of the emulation into user code - static final JSONArrayAggOrderByStep jsonArrayaggEmulation(Context ctx, Fields fields, boolean agg) { - return jsonxArrayaggEmulation(ctx, fields, agg, DSL::jsonArrayAgg, DSL::jsonObject, DSL::jsonArray); + static final JSONArrayAggOrderByStep jsonArrayaggEmulation(Context ctx, Fields fields, boolean agg, boolean distinct) { + return jsonxArrayaggEmulation(ctx, fields, agg, distinct ? DSL::jsonArrayAggDistinct : DSL::jsonArrayAgg, DSL::jsonObject, DSL::jsonArray); } - static final JSONArrayAggOrderByStep jsonbArrayaggEmulation(Context ctx, Fields fields, boolean agg) { - return jsonxArrayaggEmulation(ctx, fields, agg, DSL::jsonbArrayAgg, DSL::jsonbObject, DSL::jsonbArray); + static final JSONArrayAggOrderByStep jsonbArrayaggEmulation(Context ctx, Fields fields, boolean agg, boolean distinct) { + return jsonxArrayaggEmulation(ctx, fields, agg, distinct ? DSL::jsonbArrayAggDistinct : DSL::jsonbArrayAgg, DSL::jsonbObject, DSL::jsonbArray); } static final JSONArrayAggOrderByStep jsonxArrayaggEmulation( diff --git a/jOOQ/src/main/java/org/jooq/impl/MultisetAgg.java b/jOOQ/src/main/java/org/jooq/impl/MultisetAgg.java index 02fa01ac1b..d000864919 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MultisetAgg.java +++ b/jOOQ/src/main/java/org/jooq/impl/MultisetAgg.java @@ -115,7 +115,7 @@ final class MultisetAgg extends AbstractAggregateFunction ctx, boolean multisetCondition) { switch (emulateMultiset(ctx.configuration())) { case JSON: { - JSONArrayAggOrderByStep order = jsonArrayaggEmulation(ctx, row, true); + JSONArrayAggOrderByStep order = jsonArrayaggEmulation(ctx, row, true, false); Field f = multisetCondition ? fo((AbstractAggregateFunction) returningClob(ctx, order.orderBy(row.fields()))) @@ -130,7 +130,7 @@ final class MultisetAgg extends AbstractAggregateFunction order = jsonbArrayaggEmulation(ctx, row, true); + JSONArrayAggOrderByStep order = jsonbArrayaggEmulation(ctx, row, true, false); Field f = multisetCondition ? fo((AbstractAggregateFunction) returningClob(ctx, order.orderBy(row.fields())))