From d8eac6cc604222047cbc85e500c1b4dc49408c10 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 25 Aug 2020 11:30:25 +0200 Subject: [PATCH] [jOOQ/jOOQ#8353] Emulate UPDATE .. SET embeddable = (SELECT ..) --- jOOQ/src/main/java/org/jooq/impl/Tools.java | 36 +++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 545ccdee82..9e94b9dc06 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -5350,9 +5350,32 @@ final class Tools { // It's an embeddable type, but it is null : field instanceof Val && EmbeddableRecord.class.isAssignableFrom(field.getType()) ? newInstance((Class>) field.getType()).valuesRow().fields() + : field instanceof ScalarSubquery + ? embeddedFields((ScalarSubquery) field) : null; } + static final Field[] embeddedFields(ScalarSubquery field) { + + // Split a scalar subquery of degree N into N scalar subqueries of degree 1 + // In a few cases, there's a better solution that prevents the N subqueries, + // but this is a good default that works in many cases. + // [#8353] [#10522] [#10523] TODO: Factor out some of this logic and + // reuse it for the emulation of UPDATE .. SET row = (SELECT ..) + List> select = field.query.getSelect(); + List> result = new ArrayList<>(); + + for (Field f : flattenCollection(select, false)) + result.add(f); + + String[] fieldNames = fieldNameStrings(result.size()); + Table t = field.query.asTable("t", fieldNames); + for (int i = 0; i < result.size(); i++) + result.set(i, DSL.field(DSL.select(DSL.field(name("t", fieldNames[i]))).from(t))); + + return result.toArray(EMPTY_FIELD); + } + private static final EmbeddableRecord newInstance(Class> type) { try { return type.getConstructor().newInstance(); @@ -5423,8 +5446,7 @@ final class Tools { @SuppressWarnings("unchecked") @Override - List flatten(E e) { - if (e instanceof EmbeddableTableField) { + Iterable flatten(E e) { @@ -5437,11 +5459,7 @@ final class Tools { - - return (List) Arrays.asList(((EmbeddableTableField) e).fields); - } - - return null; + return Tools.flatten(e); } }; } @@ -5510,7 +5528,7 @@ final class Tools { this.delegate = delegate; } - abstract List flatten(E e); + abstract Iterable flatten(E e); private final void move() { if (next == null) { @@ -5527,7 +5545,7 @@ final class Tools { if (delegate.hasNext()) { next = delegate.next(); - List flattened = flatten(next); + Iterable flattened = flatten(next); if (flattened == null) return;