[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:
parent
add0a771d8
commit
dbeafea01b
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user