diff --git a/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java b/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java index c0b1bea7cf..e684f0a716 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java +++ b/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java @@ -37,6 +37,8 @@ */ package org.jooq.impl; +import static org.jooq.SQLDialect.DERBY; +import static org.jooq.impl.DSL.selectFrom; import static org.jooq.impl.Names.N_SELECT; import static org.jooq.impl.Tools.selectQueryImpl; import static org.jooq.impl.Tools.visitSubquery; @@ -106,11 +108,22 @@ final class AliasedSelect extends AbstractTable { @Override public final void accept(Context ctx) { - Object previous = ctx.data(DATA_SELECT_ALIASES); + SelectQueryImpl q = selectQueryImpl(query); - ctx.data(DATA_SELECT_ALIASES, aliases); - visitSubquery(ctx, query); - ctx.data(DATA_SELECT_ALIASES, previous); + // [#3679] [#10540] Without standardised UNION subquery column names, + // Derby projects column indexes 1, 2, 3 as names, but + // they cannot be referenced. In that case, revert to + // actual derived table usage. + if (ctx.family() == DERBY && q != null && q.hasUnions()) { + visitSubquery(ctx, selectFrom(query.asTable(DSL.name("t"), aliases))); + } + else { + Object previous = ctx.data(DATA_SELECT_ALIASES); + + ctx.data(DATA_SELECT_ALIASES, aliases); + visitSubquery(ctx, query); + ctx.data(DATA_SELECT_ALIASES, previous); + } } @Override // Avoid AbstractTable implementation diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 0899371642..cf4c514a24 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -2279,6 +2279,10 @@ final class SelectQueryImpl extends AbstractResultQuery imp private static final Set UNION_PARENTHESIS = SQLDialect.supportedBy(DERBY, MARIADB, MYSQL); private static final Set UNION_PARENTHESIS_IN_DERIVED_TABLES = SQLDialect.supportedBy(DERBY); + final boolean hasUnions() { + return !unionOp.isEmpty(); + } + private final boolean unionOpNesting() { if (unionOp.size() > 1) return true;