From da12147ca73aa1fd5ad0ead4805273cc456a9f9f Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 20 Oct 2022 10:48:50 +0200 Subject: [PATCH] [jOOQ/jOOQ#14105] ClassCastException when nesting array(select) projections --- .../main/java/org/jooq/impl/AbstractConverter.java | 4 ++-- .../main/java/org/jooq/impl/ConvertedDataType.java | 4 ++++ jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java | 11 ++++------- jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java | 9 ++------- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractConverter.java b/jOOQ/src/main/java/org/jooq/impl/AbstractConverter.java index 20c5623fd1..86d9f3d9f6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractConverter.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractConverter.java @@ -44,8 +44,8 @@ import org.jooq.Converter; */ public abstract class AbstractConverter implements Converter { - private final Class fromType; - private final Class toType; + private final Class fromType; + private final Class toType; public AbstractConverter(Class fromType, Class toType) { this.fromType = fromType; diff --git a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java index 455dc64098..123769becf 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java @@ -320,5 +320,9 @@ final class ConvertedDataType extends AbstractDataTypeX { final DataType delegate() { return delegate instanceof ConvertedDataType c ? c.delegate() : delegate; } + + static final DataType delegate(DataType type) { + return type instanceof ConvertedDataType c ? c.delegate() : type; + } } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index ed27318986..cdd2b09863 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -4007,9 +4007,8 @@ public class DefaultBinding implements Binding { // [#4964] [#6058] Recurse only if we have a meaningful converter, not the identity converter, // which would cause a StackOverflowError, here! - else if (type != wrapper(converter.toType())) { - return converter.from((T) pgFromString(ctx, field("converted_field", ((ConvertedDataType) field.getDataType()).delegate()), string), ctx.converterContext()); - } + else if (type != wrapper(converter.toType())) + return converter.from((T) pgFromString(ctx, field("converted_field", ConvertedDataType.delegate(field.getDataType())), string), ctx.converterContext()); throw new UnsupportedOperationException("Class " + type + " is not supported"); } @@ -4063,9 +4062,6 @@ public class DefaultBinding implements Binding { /** * Create an array from a String - *

- * Unfortunately, this feature is very poorly documented and true UDT - * support by the PostGreSQL JDBC driver has been postponed for a long time. * * @param string A String representation of an array * @return The converted array @@ -4074,10 +4070,11 @@ public class DefaultBinding implements Binding { if (string == null) return null; + DataType t = field.getDataType(); try { return Tools.map( toPGArray(string), - v -> pgFromString(ctx, field("array_element", type.getComponentType()), v), + v -> pgFromString(ctx, field("array_element", ConvertedDataType.delegate(t).getArrayComponentDataType()), v), size -> (Object[]) java.lang.reflect.Array.newInstance(type.getComponentType(), size) ); } diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java index 20e2a150c8..b9148184ed 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java @@ -324,16 +324,11 @@ final class JSONEntryImpl extends AbstractQueryPart implements JSONEntry, } static final boolean isType(DataType t, Class type) { - if (t instanceof ConvertedDataType c) - t = c.delegate(); - - return t.getType() == type; + return ConvertedDataType.delegate(t).getType() == type; } static final boolean isJSON(Context ctx, DataType type) { - DataType t = type instanceof ConvertedDataType c - ? c.delegate() - : type; + DataType t = ConvertedDataType.delegate(type); return t.isJSON() || t.isEmbeddable() && forceMultisetContent(ctx, () -> t.getRow().size() > 1) && emulateMultisetWithJSON(ctx)