[jOOQ/jOOQ#14694] Re-wrap actual Val, don't create a ConvertedVal

The initial fix attempted to create a ConvertedVal from the original Val, but that didn't always produce the required bind value casts, e.g. in Firebird. When jOOQ's internals create a Val (as opposed to the user), then the interesting value is really only the value, not the wrapper, so we can discard the temporary wrapper as soon as we have explicit type information.

As an aside, it is particularly important not to apply this logic e.g. when parsing / translating SQL, in case of which we currently still rely on Val identity for caching (!)
This commit is contained in:
Lukas Eder 2023-02-27 11:01:33 +01:00
parent add0a771d8
commit dbeafea01b
2 changed files with 23 additions and 11 deletions

View File

@ -31636,8 +31636,12 @@ public class DSL {
@NotNull
@Support
public static <T> Param<T> val(T value) {
return val0(value, false);
}
static <T> Param<T> val0(T value, boolean inferredDataType) {
Class type = value == null ? Object.class : value.getClass();
return val0(value, getDataType0(type), true);
return val0(value, getDataType0(type), inferredDataType);
}
/**

View File

@ -2028,17 +2028,24 @@ final class Tools {
}
@SuppressWarnings("unchecked")
private static final <T> Field<T> field(Object value, Supplier<Field<T>> defaultValue) {
private static final <T> Field<T> field(
Object value,
boolean defaultInferred,
Function<? super Object, ? extends Param<T>> defaultValue
) {
// [#14694] Inferred data types may have to be refined lazily, here.
// For example, when wrapping row(1, 2), then the integers may
// still require a converter to be applied to them, when the
// row is passed to the INSERT's valuesOfRows() method.
if (value instanceof Val<?> p) {
if (p.inferredDataType)
return defaultValue.get();
if (value instanceof Val<?> p1) {
if (p1.inferredDataType && !defaultInferred) {
Val<T> p2 = (Val<T>) defaultValue.apply(p1.getValue());
p2.setInline0(p1.isInline());
return p2;
}
else
return (Field<T>) p;
return (Field<T>) p1;
}
// Fields can be mixed with constant values
@ -2058,23 +2065,24 @@ final class Tools {
throw fieldExpected(value);
else
return defaultValue.get();
return defaultValue.apply(value);
}
@SuppressWarnings("unchecked")
static final <T> Field<T> field(T value) {
return field(value, () -> val(value));
return field(value, true, v -> DSL.val0((T) v, true));
}
static final <T> Field<T> field(Object value, Field<T> field) {
return field(value, () -> val(value, field));
return field(value, false, v -> val(v, field));
}
static final <T> Field<T> field(Object value, Class<T> type) {
return field(value, () -> val(value, type));
return field(value, false, v -> val(v, type));
}
static final <T> Field<T> field(Object value, DataType<T> type) {
return field(value, () -> val(value, type));
return field(value, false, v -> val(v, type));
}
static final <T> List<Field<T>> fields(T[] values) {