diff --git a/jOOQ/src/main/java/org/jooq/impl/FetchCount.java b/jOOQ/src/main/java/org/jooq/impl/FetchCount.java index aeaf41d460..1095105a02 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FetchCount.java +++ b/jOOQ/src/main/java/org/jooq/impl/FetchCount.java @@ -72,7 +72,7 @@ final class FetchCount extends AbstractResultQuery> { @Override public final void accept(Context ctx) { - ctx.visit(delegate(ctx.configuration())); + ctx.visit(select(count).from(new AliasedSelect<>(query).as("t"))); } private final QueryPart delegate(Configuration configuration) { diff --git a/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java b/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java index a857c4c426..5fc7e42cb9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java +++ b/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java @@ -65,7 +65,6 @@ import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.selectCount; import static org.jooq.impl.Keywords.K_IS_NOT_NULL; import static org.jooq.impl.Keywords.K_IS_NULL; -import static org.jooq.impl.Tools.fieldNameStrings; import static org.jooq.impl.Tools.visitSubquery; import java.util.ArrayList; @@ -128,7 +127,7 @@ final class RowIsNull extends AbstractCondition { if (row != null && EMULATE_NULL_ROW.contains(ctx.dialect())) ctx.visit(condition(row.fields())); else if (select != null && EMULATE_NULL_QUERY.contains(ctx.dialect())) { - Table t = select.asTable("t", fieldNameStrings(select.getSelect().size())); + Table t = new AliasedSelect<>(select).as("t"); ctx.visit(inline(1).eq(selectCount().from(t).where(condition(t.fields())))); } else diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 785dcca221..61fb61e0b4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -162,6 +162,7 @@ import static org.jooq.impl.Tools.BooleanDataKey.DATA_WRAP_DERIVED_TABLES_IN_PAR import static org.jooq.impl.Tools.DataKey.DATA_COLLECTED_SEMI_ANTI_JOIN; import static org.jooq.impl.Tools.DataKey.DATA_DML_TARGET_TABLE; import static org.jooq.impl.Tools.DataKey.DATA_OVERRIDE_ALIASES_IN_ORDER_BY; +import static org.jooq.impl.Tools.DataKey.DATA_SELECT_ALIASES; import static org.jooq.impl.Tools.DataKey.DATA_SELECT_INTO_TABLE; import static org.jooq.impl.Tools.DataKey.DATA_TOP_LEVEL_CTE; import static org.jooq.impl.Tools.DataKey.DATA_WINDOW_DEFINITIONS; @@ -929,7 +930,25 @@ final class SelectQueryImpl extends AbstractResultQuery imp // of jOOQ should implement a push / pop semantics to clearly delimit such scope. Object renderTrailingLimit = context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE); Object localWindowDefinitions = context.data(DATA_WINDOW_DEFINITIONS); + Name[] selectAliases = (Name[]) context.data(DATA_SELECT_ALIASES); + try { + Field[] originalFields = null; + Field[] alternativeFields = null; + + if (selectAliases != null) { + context.data().remove(DATA_SELECT_ALIASES); + + originalFields = getSelect().toArray(EMPTY_FIELD); + alternativeFields = new Field[originalFields.length]; + + for (int i = 0; i < originalFields.length; i++) + if (i < selectAliases.length) + alternativeFields[i] = originalFields[i].as(selectAliases[i]); + else + alternativeFields[i] = originalFields[i]; + } + if (TRUE.equals(renderTrailingLimit)) context.data().remove(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE); @@ -1118,14 +1137,14 @@ final class SelectQueryImpl extends AbstractResultQuery imp if (getLimit().isApplicable() && getLimit().withTies()) toSQLReferenceLimitWithWindowFunctions(context); else - toSQLReferenceLimitDefault(context); + toSQLReferenceLimitDefault(context, originalFields, alternativeFields); break; } // By default, render the dialect's limit clause default: { - toSQLReferenceLimitDefault(context); + toSQLReferenceLimitDefault(context, originalFields, alternativeFields); break; } @@ -1193,8 +1212,11 @@ final class SelectQueryImpl extends AbstractResultQuery imp context.data(DATA_WINDOW_DEFINITIONS, localWindowDefinitions); if (renderTrailingLimit != null) context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE, renderTrailingLimit); + if (selectAliases != null) + context.data(DATA_SELECT_ALIASES, selectAliases); } + context.scopeEnd(); } @@ -1219,11 +1241,11 @@ final class SelectQueryImpl extends AbstractResultQuery imp /** * The default LIMIT / OFFSET clause in most dialects */ - private final void toSQLReferenceLimitDefault(Context context) { + private final void toSQLReferenceLimitDefault(Context context, Field[] originalFields, Field[] alternativeFields) { Object data = context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE); context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE, true); - toSQLReference0(context); + toSQLReference0(context, originalFields, alternativeFields); if (data == null) context.data().remove(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE); @@ -1417,14 +1439,6 @@ final class SelectQueryImpl extends AbstractResultQuery imp - - /** - * This method renders the main part of a query without the LIMIT clause. - * This part is common to any type of limited query - */ - private final void toSQLReference0(Context context) { - toSQLReference0(context, null, null); - } /** * This method renders the main part of a query without the LIMIT clause. diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index bf982375ac..d880834471 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -610,9 +610,16 @@ final class Tools { DATA_ON_DUPLICATE_KEY_WHERE, /** - * [#3607] [#8522] CTEs that need to be added to the top level CTE section. + * [#3607] [#8522] CTEs that need to be added to the top level CTE + * section. */ - DATA_TOP_LEVEL_CTE + DATA_TOP_LEVEL_CTE, + + /** + * [#10540] Aliases to be applied to the current SELECT + * statement. + */ + DATA_SELECT_ALIASES } /** @@ -3106,6 +3113,16 @@ final class Tools { + + @SuppressWarnings("unchecked") + static final SelectQueryImpl selectQueryImpl(Select select) { + if (select instanceof SelectQueryImpl) + return (SelectQueryImpl) select; + else if (select instanceof AbstractDelegatingQuery) + return ((AbstractDelegatingQuery>) select).getDelegate(); + else + return null; + } /** * Add primary key conditions to a query