[jOOQ/jOOQ#14694] INSERT statement does not apply types to bind values in VALUES clause when using valuesOfRows()
This commit is contained in:
parent
849d4ec9e2
commit
4c63a20d2a
@ -29976,7 +29976,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support
|
||||
public static <T> Param<T> param(DataType<T> type) {
|
||||
return new Val<>(null, type);
|
||||
return new Val<>(null, type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -30038,7 +30038,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support
|
||||
public static <T> Param<T> param(String name, DataType<T> type) {
|
||||
return new Val<>(null, type, name);
|
||||
return new Val<>(null, type, false, name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -30073,7 +30073,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support
|
||||
public static <T> Param<T> param(String name, T value) {
|
||||
return new Val<>(value, Tools.field(value).getDataType(), name);
|
||||
return new Val<>(value, Tools.field(value).getDataType(), true, name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31603,7 +31603,7 @@ public class DSL {
|
||||
@Support
|
||||
public static <T> Param<T> val(T value) {
|
||||
Class type = value == null ? Object.class : value.getClass();
|
||||
return val(value, getDataType0(type));
|
||||
return val0(value, getDataType0(type), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32064,6 +32064,10 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support
|
||||
public static <T> Param<T> val(Object value, DataType<T> type) {
|
||||
return val0(value, type, false);
|
||||
}
|
||||
|
||||
private static <T> Param<T> val0(Object value, DataType<T> type, boolean inferredDataType) {
|
||||
|
||||
// Advanced data types have dedicated constant types
|
||||
if (value instanceof QualifiedRecord<?> r)
|
||||
@ -32079,9 +32083,14 @@ public class DSL {
|
||||
|
||||
|
||||
|
||||
|
||||
// [#14694] value can be a Param contained in a Row
|
||||
else if (value instanceof Val<?> p)
|
||||
return p.convertTo(type);
|
||||
|
||||
// The default behaviour
|
||||
T converted = type.convert(value);
|
||||
return new Val<>(converted, mostSpecific(converted, type));
|
||||
return new Val<>(converted, mostSpecific(converted, type), inferredDataType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2030,8 +2030,19 @@ final class Tools {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final <T> Field<T> field(Object value, Supplier<Field<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();
|
||||
else
|
||||
return (Field<T>) p;
|
||||
}
|
||||
|
||||
// Fields can be mixed with constant values
|
||||
if (value instanceof Field<?>)
|
||||
else if (value instanceof Field<?>)
|
||||
return (Field<T>) value;
|
||||
|
||||
// [#6362] [#8220] Single-column selects can be considered fields, too
|
||||
@ -3317,7 +3328,7 @@ final class Tools {
|
||||
else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Object> type = (Class<Object>) (substitute != null ? substitute.getClass() : Object.class);
|
||||
result.add(new Val<>(substitute, DSL.getDataType(type)));
|
||||
result.add(new Val<>(substitute, DSL.getDataType(type), true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -96,12 +96,29 @@ final class Val<T> extends AbstractParam<T> implements UEmpty {
|
||||
private static final JooqLogger log = JooqLogger.getLogger(Val.class);
|
||||
private static final ConcurrentHashMap<Class<?>, Object> legacyWarnings = new ConcurrentHashMap<>();
|
||||
|
||||
Val(T value, DataType<T> type) {
|
||||
/**
|
||||
* [#14694] Whether the data type was inferred as opposed to provided
|
||||
* explicitly.
|
||||
* <p>
|
||||
* Numerous features depend on an inferred data type being overriden lazily
|
||||
* once the information is available, e.g. when passing around a row(1, 2)
|
||||
* to an <code>INSERT</code> statement, the initial type information should
|
||||
* be overridden once the row is copied to the statement. It is different
|
||||
* from when users provide type information explicitly, such as row(val(1,
|
||||
* INTEGER), val(2, INTEGER)).
|
||||
*/
|
||||
final boolean inferredDataType;
|
||||
|
||||
Val(T value, DataType<T> type, boolean inferredDataType) {
|
||||
super(value, type(value, type));
|
||||
|
||||
this.inferredDataType = inferredDataType;
|
||||
}
|
||||
|
||||
Val(T value, DataType<T> type, String paramName) {
|
||||
Val(T value, DataType<T> type, boolean inferredDataType, String paramName) {
|
||||
super(value, type(value, type), paramName);
|
||||
|
||||
this.inferredDataType = inferredDataType;
|
||||
}
|
||||
|
||||
private static final <T> DataType<T> type(T value, DataType<T> type) {
|
||||
@ -116,7 +133,7 @@ final class Val<T> extends AbstractParam<T> implements UEmpty {
|
||||
* [#10438] Convert this bind value to a new type.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
final <U> Field<U> convertTo(DataType<U> type) {
|
||||
final <U> Param<U> convertTo(DataType<U> type) {
|
||||
|
||||
// [#10438] A user defined data type could was not provided explicitly,
|
||||
// when wrapping a bind value in DSL::val or DSL::inline
|
||||
@ -146,13 +163,13 @@ final class Val<T> extends AbstractParam<T> implements UEmpty {
|
||||
}
|
||||
|
||||
final Val<T> copy(Object newValue) {
|
||||
Val<T> w = new Val<>(getDataType().convert(newValue), getDataType(), getParamName());
|
||||
Val<T> w = new Val<>(getDataType().convert(newValue), getDataType(), inferredDataType, getParamName());
|
||||
w.setInline0(isInline());
|
||||
return w;
|
||||
}
|
||||
|
||||
final <U> Val<U> convertTo0(DataType<U> type) {
|
||||
Val<U> w = new Val<>(type.convert(getValue()), type, getParamName());
|
||||
Val<U> w = new Val<>(type.convert(getValue()), type, inferredDataType, getParamName());
|
||||
w.setInline0(isInline());
|
||||
return w;
|
||||
}
|
||||
@ -358,7 +375,7 @@ final class Val<T> extends AbstractParam<T> implements UEmpty {
|
||||
|
||||
@Override
|
||||
public final Param<T> $inline(boolean inline) {
|
||||
Val<T> w = new Val<>(value, getDataType(), getParamName());
|
||||
Val<T> w = new Val<>(value, getDataType(), inferredDataType, getParamName());
|
||||
w.setInline0(inline);
|
||||
return w;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user