diff --git a/jOOQ/src/main/java/org/jooq/JSONArrayNullStep.java b/jOOQ/src/main/java/org/jooq/JSONArrayNullStep.java index dcd6ab273f..58936581dc 100644 --- a/jOOQ/src/main/java/org/jooq/JSONArrayNullStep.java +++ b/jOOQ/src/main/java/org/jooq/JSONArrayNullStep.java @@ -84,7 +84,7 @@ public interface JSONArrayNullStep extends JSONArrayReturningStep { *

* Exclude NULL values in output JSON. */ - @Support({ H2, POSTGRES, SQLITE, TRINO, YUGABYTEDB }) + @Support({ H2, MARIADB, POSTGRES, SQLITE, TRINO, YUGABYTEDB }) @NotNull @CheckReturnValue JSONArrayReturningStep absentOnNull(); } diff --git a/jOOQ/src/main/java/org/jooq/JSONObjectNullStep.java b/jOOQ/src/main/java/org/jooq/JSONObjectNullStep.java index f29b5066db..79acb6618b 100644 --- a/jOOQ/src/main/java/org/jooq/JSONObjectNullStep.java +++ b/jOOQ/src/main/java/org/jooq/JSONObjectNullStep.java @@ -84,7 +84,7 @@ public interface JSONObjectNullStep extends JSONObjectReturningStep { *

* Exclude NULL values in output JSON. */ - @Support({ H2, MYSQL, POSTGRES, SQLITE, TRINO, YUGABYTEDB }) + @Support({ H2, MARIADB, MYSQL, POSTGRES, SQLITE, TRINO, YUGABYTEDB }) @NotNull @CheckReturnValue JSONObjectReturningStep absentOnNull(); } diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONArray.java b/jOOQ/src/main/java/org/jooq/impl/JSONArray.java index 9c642203c9..4243b144bd 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONArray.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONArray.java @@ -37,34 +37,57 @@ */ package org.jooq.impl; -import static org.jooq.impl.DSL.*; -import static org.jooq.impl.DSL.field; -import static org.jooq.impl.Internal.*; +// ... +import static org.jooq.SQLDialect.H2; +import static org.jooq.impl.DSL.array; +import static org.jooq.impl.DSL.function; +import static org.jooq.impl.DSL.inline; +import static org.jooq.impl.DSL.jsonArray; +import static org.jooq.impl.DSL.jsonArrayAgg; +import static org.jooq.impl.DSL.jsonTable; +import static org.jooq.impl.DSL.jsonbArrayAgg; +import static org.jooq.impl.DSL.rand; +import static org.jooq.impl.DSL.row; +import static org.jooq.impl.DSL.select; +import static org.jooq.impl.DSL.values; import static org.jooq.impl.JSONEntryImpl.jsonCastMapper; -import static org.jooq.impl.Keywords.*; -import static org.jooq.impl.Names.*; -import static org.jooq.impl.SQLDataType.*; -import static org.jooq.impl.Tools.*; -import static org.jooq.impl.Tools.BooleanDataKey.*; -import static org.jooq.impl.Tools.ExtendedDataKey.*; -import static org.jooq.impl.Tools.SimpleDataKey.*; -import static org.jooq.SQLDialect.*; +import static org.jooq.impl.Names.N_ARRAY_CONSTRUCT; +import static org.jooq.impl.Names.N_ARRAY_CONSTRUCT_COMPACT; +import static org.jooq.impl.Names.N_JSONB_BUILD_ARRAY; +import static org.jooq.impl.Names.N_JSON_ARRAY; +import static org.jooq.impl.Names.N_JSON_BUILD_ARRAY; +import static org.jooq.impl.Names.N_JSON_EXTRACT; +import static org.jooq.impl.Names.N_JSON_MODIFY; +import static org.jooq.impl.Names.N_JSON_QUERY; +import static org.jooq.impl.Names.N_JSON_TREE; +import static org.jooq.impl.Names.N_KEY; +import static org.jooq.impl.Names.N_T; +import static org.jooq.impl.Names.N_TUPLE; +import static org.jooq.impl.Names.N_VALUE; +import static org.jooq.impl.Names.N_toJSONString; +import static org.jooq.impl.SQLDataType.JSON; +import static org.jooq.impl.SQLDataType.JSONB; +import static org.jooq.impl.SQLDataType.OTHER; +import static org.jooq.impl.SQLDataType.VARCHAR; +import static org.jooq.impl.Tools.anyMatch; +import static org.jooq.impl.Tools.map; -import org.jooq.*; -import org.jooq.Function1; -import org.jooq.Record; -import org.jooq.conf.ParamType; +import java.util.Collection; + +import org.jooq.Context; +import org.jooq.DataType; +import org.jooq.Field; +import org.jooq.Function4; +import org.jooq.JSON; +import org.jooq.JSONArrayNullStep; +import org.jooq.JSONArrayReturningStep; +import org.jooq.Param; +// ... +import org.jooq.Row1; +import org.jooq.Table; import org.jooq.impl.QOM.JSONOnNull; import org.jooq.tools.StringUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - /** @@ -238,6 +261,30 @@ implements break; } + case MARIADB: { + if (onNull == JSONOnNull.ABSENT_ON_NULL) { + Field value = DSL.field(N_VALUE, getDataType()); + + ctx.visit( + DSL.coalesce( + DSL.field( + select(jsonArrayAgg(function(N_JSON_EXTRACT, getDataType(), value, inline("$")))) + .from(jsonTable((Field) $onNull(JSONOnNull.NULL_ON_NULL), inline("$[*]")) + .column(value, SQLDataType.JSON).path("$").as(N_T)) + .where(value.ne((Field) inline("null"))) + + // [#10113] Workaround for https://jira.mariadb.org/projects/MDEV/issues/MDEV-34284 + .and(rand().isNotNull()) + ), + jsonArray() + )); + } + else + acceptStandard(ctx, mapped); + + break; + } + case SQLITE: { if (onNull == JSONOnNull.ABSENT_ON_NULL) { Field key = DSL.field(N_KEY, VARCHAR); diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONObject.java b/jOOQ/src/main/java/org/jooq/impl/JSONObject.java index 14a4a6259a..e300b411a2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONObject.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONObject.java @@ -39,6 +39,7 @@ package org.jooq.impl; import static org.jooq.impl.DSL.*; import static org.jooq.impl.Internal.*; +import static org.jooq.impl.JSONEntryImpl.jsonMerge; import static org.jooq.impl.Keywords.*; import static org.jooq.impl.Names.*; import static org.jooq.impl.SQLDataType.*; @@ -211,11 +212,17 @@ implements // Workaround for https://jira.mariadb.org/browse/MDEV-13701 if (entries.size() > 1) { - ctx.visit(JSONEntryImpl.jsonMerge(ctx, "{}", Tools.map(entries, e -> jsonObject(e), Field[]::new))); + ctx.visit(jsonMerge(ctx, "{}", + map(entries, onNull == JSONOnNull.ABSENT_ON_NULL + ? e -> DSL.nvl2(e.value(), jsonObject(e), jsonObject()) + : e -> jsonObject(e) + , Field[]::new + ) + )); } else if (!entries.isEmpty() && isJSONArray((first = entries.iterator().next()).value())) { ctx.visit(jsonObject( - key(first.key()).value(JSONEntryImpl.jsonMerge(ctx, "[]", first.value())) + key(first.key()).value(jsonMerge(ctx, "[]", first.value())) )); } else