From dbeafea01b0c9f41632960681ce7ef33d36a6df6 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 27 Feb 2023 11:01:33 +0100 Subject: [PATCH] [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 (!) --- jOOQ/src/main/java/org/jooq/impl/DSL.java | 6 ++++- jOOQ/src/main/java/org/jooq/impl/Tools.java | 28 +++++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 89271402fe..010e8d026c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -31636,8 +31636,12 @@ public class DSL { @NotNull @Support public static Param val(T value) { + return val0(value, false); + } + + static Param 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); } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 9b4e039a53..99131002ed 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -2028,17 +2028,24 @@ final class Tools { } @SuppressWarnings("unchecked") - private static final Field field(Object value, Supplier> defaultValue) { + private static final Field field( + Object value, + boolean defaultInferred, + Function> 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 p2 = (Val) defaultValue.apply(p1.getValue()); + p2.setInline0(p1.isInline()); + return p2; + } else - return (Field) p; + return (Field) 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 Field field(T value) { - return field(value, () -> val(value)); + return field(value, true, v -> DSL.val0((T) v, true)); } static final Field field(Object value, Field field) { - return field(value, () -> val(value, field)); + return field(value, false, v -> val(v, field)); } static final Field field(Object value, Class type) { - return field(value, () -> val(value, type)); + return field(value, false, v -> val(v, type)); } static final Field field(Object value, DataType type) { - return field(value, () -> val(value, type)); + return field(value, false, v -> val(v, type)); } static final List> fields(T[] values) {