[jOOQ/jOOQ#17124] MySQL boolean type information isn't maintained across

expressions when embedded into JSON
This commit is contained in:
Lukas Eder 2024-08-22 11:55:45 +02:00
parent 0fe17b977e
commit ab348020b7

View File

@ -51,6 +51,7 @@ import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.inlined;
import static org.jooq.impl.DSL.not;
import static org.jooq.impl.DSL.nvl;
import static org.jooq.impl.DSL.toChar;
import static org.jooq.impl.DSL.when;
@ -60,6 +61,7 @@ import static org.jooq.impl.Keywords.K_KEY;
import static org.jooq.impl.Keywords.K_VALUE;
import static org.jooq.impl.Names.N_HEX;
import static org.jooq.impl.Names.N_JSON;
import static org.jooq.impl.Names.N_JSON_ARRAY;
import static org.jooq.impl.Names.N_JSON_EXTRACT;
import static org.jooq.impl.Names.N_JSON_MERGE;
import static org.jooq.impl.Names.N_JSON_MERGE_PRESERVE;
@ -232,7 +234,7 @@ final class JSONEntryImpl<T> extends AbstractQueryPart implements JSONEntry<T>,
if (type.getSQLDataType() == BIT)
return field.cast(BOOLEAN);
else if (isType(type, Boolean.class))
return inlined(field);
return booleanJsonExtract((Field<Boolean>) field);
else if (castJSONTypes && type.isJSON())
if (ctx.family() == MYSQL)
return field.cast(field.getDataType());
@ -358,9 +360,20 @@ final class JSONEntryImpl<T> extends AbstractQueryPart implements JSONEntry<T>,
private static final Field<?> booleanJsonExtract(Field<Boolean> field) {
return Tools.isVal1(field, v -> v.isInline())
? field
: when(field, booleanJsonExtract0(inline(true)))
.when(not(field), booleanJsonExtract0(inline(false)));
}
private static final Field<JSON> booleanJsonExtract0(Field<?> field) {
return function(N_JSON_EXTRACT, JSON, function(N_JSON_ARRAY, JSON, field), inline("$[0]"));
}
@SuppressWarnings("unchecked")
private static Field<String> booleanCase(Field<?> field) {
private static final Field<String> booleanCase(Field<?> field) {
return case_((Field<Boolean>) field).when(inline(true), inline("true")).when(inline(false), inline("false"));
}