diff --git a/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java b/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java index 4b456ab9a3..5edc425659 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java @@ -116,15 +116,6 @@ final class ArrayTable extends AbstractTable implements UNotYetImplement this.field = init(arrayType, this.alias, this.fieldAliases[0]); } - @SuppressWarnings("removal") - static final DataType componentDataType(Object[] array) { - if (!isEmpty(array) && array[0] instanceof Field f) { - return f.getDataType(); - } - else - return DSL.getDataType(array.getClass().getComponentType()); - } - static final FieldsImpl init(Class arrayType, Name alias, Name fieldAlias) { // [#1114] [#7863] VARRAY/TABLE of OBJECT have more than one field diff --git a/jOOQ/src/main/java/org/jooq/impl/ArrayTableEmulation.java b/jOOQ/src/main/java/org/jooq/impl/ArrayTableEmulation.java index 328a0460e2..fed5641350 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ArrayTableEmulation.java +++ b/jOOQ/src/main/java/org/jooq/impl/ArrayTableEmulation.java @@ -43,6 +43,7 @@ import static org.jooq.impl.DSL.one; import static org.jooq.impl.DSL.using; import static org.jooq.impl.Names.N_ARRAY_TABLE; import static org.jooq.impl.Names.N_COLUMN_VALUE; +import static org.jooq.impl.Tools.componentDataType; import org.jooq.Configuration; import org.jooq.Context; @@ -83,7 +84,7 @@ final class ArrayTableEmulation extends AbstractTable implements UTransi this.array = array; this.alias = alias; this.fieldAlias = fieldAlias == null ? N_COLUMN_VALUE : fieldAlias; - this.field = new FieldsImpl<>(DSL.field(name(alias.last(), this.fieldAlias.last()), ArrayTable.componentDataType(array))); + this.field = new FieldsImpl<>(DSL.field(name(alias.last(), this.fieldAlias.last()), componentDataType(array))); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index edba59d32e..bf7e8f0e48 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -125,6 +125,7 @@ import static org.jooq.impl.Tools.combine; import static org.jooq.impl.Tools.configuration; import static org.jooq.impl.Tools.isEmpty; import static org.jooq.impl.Tools.map; +import static org.jooq.impl.Tools.mostSpecificArray; import static org.jooq.tools.StringUtils.isEmpty; import java.math.BigDecimal; @@ -11261,8 +11262,12 @@ public class DSL { @NotNull @Support public static Table unnest(Object[] array) { - if (!isEmpty(array) && array[0] instanceof Field) + boolean notEmpty = !isEmpty(array); + + if (notEmpty && array[0] instanceof Field) return new ArrayOfValues(Tools.fieldsArray(array)); + else if (notEmpty && array.getClass() == Object[].class) + return unnest0(val(mostSpecificArray(array))); else return unnest0(val(array)); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 4b69a6dce1..0166987444 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -7262,4 +7262,31 @@ final class Tools { return !FALSE.equals(ctx.settings().isRenderVariablesInDerivedTablesForEmulations()) && !NO_SUPPORT_CORRELATED_DERIVED_TABLE.contains(ctx.dialect()); } + + @SuppressWarnings("removal") + static final DataType componentDataType(Object[] array) { + if (!isEmpty(array) && array[0] instanceof Field f) { + return f.getDataType(); + } + else + return DSL.getDataType(array.getClass().getComponentType()); + } + + static final Object[] mostSpecificArray(Object[] array) { + if (isEmpty(array)) + return array; + + Class type = null; + for (Object o : array) + if (o != null) + if (type == null) + type = o.getClass(); + else if (type != o.getClass()) + return array; + + if (type == null) + return array; + else + return Convert.convertArray(array, type); + } }