[jOOQ/jOOQ#12085] Work around Oracle's JSON_ARRAYAGG() bugs when aggregate inputs should be DISTINCT

This commit is contained in:
Lukas Eder 2021-06-30 11:19:53 +02:00
parent 5249e2efe6
commit 47da079332
3 changed files with 39 additions and 4 deletions

View File

@ -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<J>
extends AbstractAggregateFunction<J>
implements JSONArrayAggOrderByStep<J> {
static final Set<SQLDialect> EMULATE_WITH_GROUP_CONCAT = SQLDialect.supportedBy(MARIADB, MYSQL);
static final Set<SQLDialect> SUPPORT_JSON_MERGE_PRESERVE = SQLDialect.supportedBy(MARIADB, MYSQL);
private JSONOnNull onNull;
private DataType<?> returning;
@ -250,4 +259,15 @@ implements JSONArrayAggOrderByStep<J> {
public final JSONArrayAgg<J> orderBy(Collection<? extends OrderField<?>> fields) {
return (JSONArrayAgg<J>) super.orderBy(fields);
}
static final <R extends Record> Select<R> patchOracleArrayAggBug(Configuration configuration, SelectHavingStep<R> select) {
return select;
}
}

View File

@ -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<R extends Record> extends AbstractField<Result<R>> {
if (multisetCondition)
filter = order.orderBy(t.fields());
Select<Record1<JSON>> s = select(DSL.coalesce(filter, jsonArray())).from(t);
Select<Record1<JSON>> 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<R extends Record> extends AbstractField<Result<R>> {
if (multisetCondition)
filter = order.orderBy(t.fields());
Select<Record1<JSONB>> s = select(DSL.coalesce(filter, jsonbArray())).from(t);
Select<Record1<JSONB>> s = patchOracleArrayAggBug(
ctx.configuration(),
select(DSL.coalesce(filter, jsonbArray())).from(t)
);
visitSubquery(ctx, s, true);
break;
}

View File

@ -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 <code>SELECT</code> statement that can be combined with
@ -1222,6 +1223,11 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp