[jOOQ/jOOQ#10769] Cannot convert from UUID to JSON in H2's JSON_OBJECT() and related functions

This commit is contained in:
Lukas Eder 2020-10-21 12:15:48 +02:00
parent 3f063e2df6
commit 477df78c13
4 changed files with 37 additions and 3 deletions

View File

@ -43,6 +43,7 @@ import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.impl.DSL.values;
import static org.jooq.impl.JSONEntryImpl.jsonCastMapper;
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
import static org.jooq.impl.Keywords.K_JSON_ARRAY;
@ -115,8 +116,10 @@ final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J
case POSTGRES:
if (nullType == ABSENT_ON_NULL) {
Row1[] rows = new Row1[args.size()];
for (int i = 0; i < rows.length; i++)
rows[i] = row(args.get(i));
Table<?> t = values(rows).as("t", "a");
Field<?> a = t.field("a");
ctx.visit(DSL.field(select(jsonArrayAgg(a)).from(t).where(a.isNotNull())));
@ -136,7 +139,7 @@ final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J
else
jsonNull = new JSONNull(nullType);
ctx.visit(K_JSON_ARRAY).sql('(').visit(wrap(args, jsonNull).separator("")).sql(')');
ctx.visit(K_JSON_ARRAY).sql('(').visit(wrap(wrap(args).map(jsonCastMapper(ctx)), jsonNull).separator("")).sql(')');
break;
}
}

View File

@ -43,6 +43,7 @@ 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.JSONEntryImpl.jsonCast;
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
import static org.jooq.impl.Names.N_JSONB_AGG;
@ -157,7 +158,7 @@ implements JSONArrayAggOrderByStep<J> {
private final void acceptStandard(Context<?> ctx) {
ctx.visit(N_JSON_ARRAYAGG).sql('(');
ctx.visit(arguments.get(0));
ctx.visit(jsonCast(ctx, arguments.get(0)));
acceptOrderBy(ctx);
JSONNull jsonNull = new JSONNull(nullType);

View File

@ -42,8 +42,12 @@ import static org.jooq.impl.Keywords.K_FORMAT;
import static org.jooq.impl.Keywords.K_JSON;
import static org.jooq.impl.Keywords.K_KEY;
import static org.jooq.impl.Keywords.K_VALUE;
import static org.jooq.impl.SQLDataType.VARCHAR;
import java.util.UUID;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.JSONEntry;
@ -106,8 +110,32 @@ final class JSONEntryImpl<T> extends AbstractQueryPart implements JSONEntry<T> {
break;
default:
ctx.visit(K_KEY).sql(' ').visit(key).sql(' ').visit(K_VALUE).sql(' ').visit(value);
ctx.visit(K_KEY).sql(' ').visit(key).sql(' ').visit(K_VALUE).sql(' ').visit(jsonCast(ctx, value));
break;
}
}
static final F1<Field<?>, Field<?>> jsonCastMapper(final Context<?> ctx) {
return new F1<Field<?>, Field<?>>() {
@Override
public Field<?> apply(Field<?> field) {
return jsonCast(ctx, field);
}
};
}
static final Field<?> jsonCast(Context<?> ctx, Field<?> field) {
switch (ctx.family()) {
// [#10769] Some dialects don't support auto conversions from X to JSON
case H2: {
DataType<?> type = field.getDataType();
if (type.getType() == UUID.class)
return field.cast(VARCHAR(36));
}
}
return field;
}
}

View File

@ -54,8 +54,10 @@ import static org.jooq.impl.Names.N_JSON_MERGE;
import static org.jooq.impl.Names.N_JSON_OBJECT;
import static org.jooq.impl.Names.N_T;
import static org.jooq.impl.QueryPartListView.wrap;
import static org.jooq.impl.SQLDataType.VARCHAR;
import java.util.Collection;
import java.util.UUID;
import org.jooq.Context;
import org.jooq.DataType;