diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java index 14d290ea6f..a980b6f213 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java @@ -308,10 +308,6 @@ implements return s1; } - final boolean isWindow() { - return windowSpecification != null || windowDefinition != null || windowName != null; - } - /** * Type safe NVL2(y, x, null) for statistical function * emulations. diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractWindowFunction.java b/jOOQ/src/main/java/org/jooq/impl/AbstractWindowFunction.java index 6367b8fff7..54229f617a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractWindowFunction.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractWindowFunction.java @@ -173,6 +173,10 @@ implements return null; } + final boolean isWindow() { + return windowSpecification != null || windowDefinition != null || windowName != null; + } + final void acceptOverClause(Context ctx) { QueryPart window = window(ctx); diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index ed78d32ced..1164abe4cd 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -435,30 +435,22 @@ final class SelectQueryImpl extends AbstractResultQuery imp this.localQueryPartMapping = new LinkedHashMap<>(); } + private enum CopyClause { + START, + WHERE, + QUALIFY, + END; + + final boolean between(CopyClause startInclusive, CopyClause endExclusive) { + return compareTo(startInclusive) >= 0 && compareTo(endExclusive) < 0; + } + } + /** * Whether any clauses logically following the WHERE clause are * present. */ - private final boolean stopsAtWhere() { - return stopsAtQualify() - && !qualify.hasWhere() - && window == null - && !having.hasWhere() - && Tools.isEmpty(groupBy) - && !grouping - - - - - - ; - } - - /** - * Whether any clauses logically following the QUALIFY clause - * are present. - */ - private final boolean stopsAtQualify() { + private final boolean stopsAt(CopyClause clause) { return !unionLimit.isApplicable() && Tools.isEmpty(unionSeek) && !unionSeekBefore @@ -487,123 +479,98 @@ final class SelectQueryImpl extends AbstractResultQuery imp && !distinct && hint == null && Tools.isEmpty(select) + && (clause == CopyClause.QUALIFY || + !qualify.hasWhere() + && window == null + && !having.hasWhere() + && Tools.isEmpty(groupBy) + && !grouping + + + + + + ) ; } - /** - * Copy all clauses up to the WHERE clause into a new query. - */ - private final SelectQueryImpl copyToWhere(SelectQueryImpl result) { - result.from.addAll(from); - result.condition.setWhere(condition.getWhere()); + private final SelectQueryImpl copyTo(CopyClause clause, SelectQueryImpl result) { + return copyBetween(CopyClause.START, clause, result); + } + + private final SelectQueryImpl copyAfter(CopyClause clause, SelectQueryImpl result) { + return copyBetween(clause, CopyClause.END, result); + } + + private final SelectQueryImpl copyBetween(CopyClause start, CopyClause end, SelectQueryImpl result) { + if (CopyClause.START.between(start, end)) { + result.from.addAll(from); + result.condition.setWhere(condition.getWhere()); + } + + if (CopyClause.WHERE.between(start, end)) { + + + + + + + result.grouping = grouping; + result.groupBy = groupBy; + result.having.setWhere(having.getWhere()); + if (window != null) + result.addWindow(window); + result.qualify.setWhere(qualify.getWhere()); + } + + if (CopyClause.QUALIFY.between(start, end)) { + result.select.addAll(select); + result.hint = hint; + result.distinct = distinct; + result.distinctOn = distinctOn; + result.orderBy.addAll(orderBy); + + + + result.seek.addAll(seek); + result.limit.from(limit); + result.forLock = forLock; + + + + + + + result.option = option; + result.intoTable = intoTable; + + // TODO: Should the remaining union subqueries also be copied? + result.union.addAll(union); + result.unionOp.addAll(unionOp); + result.unionOrderBy.addAll(unionOrderBy); + + + + result.unionSeek.addAll(unionSeek); + result.unionSeekBefore = unionSeekBefore; + result.unionLimit.from(unionLimit); + } return result; } - /** - * Copy all clauses up to the QUALIFY clause into a new query. - */ - private final SelectQueryImpl copyToQualify(SelectQueryImpl result) { - return copyAfterWhereToQualify(copyToWhere(result)); - } - - /** - * Copy all clauses between to the WHERE clause and the - * QUALIFY clause into a new query. - */ - private final SelectQueryImpl copyAfterWhereToQualify(SelectQueryImpl result) { - - - - - - result.grouping = grouping; - result.groupBy = groupBy; - result.having.setWhere(having.getWhere()); - if (window != null) - result.addWindow(window); - result.qualify.setWhere(qualify.getWhere()); - - return result; - } - - /** - * Copy all clauses after the WHERE clause. - */ - private final SelectQueryImpl copyAfterWhere(SelectQueryImpl result) { - return copyAfterQualify(copyAfterWhereToQualify(result)); - } - - /** - * Copy all clauses after the QUALIFY clause. - */ - private final SelectQueryImpl copyAfterQualify(SelectQueryImpl result) { - - result.select.addAll(select); - result.hint = hint; - result.distinct = distinct; - result.distinctOn = distinctOn; - result.orderBy.addAll(orderBy); - - - - result.seek.addAll(seek); - result.limit.from(limit); - result.forLock = forLock; - - - - - - - result.option = option; - result.intoTable = intoTable; - - // TODO: Should the remaining union subqueries also be copied? - result.union.addAll(union); - result.unionOp.addAll(unionOp); - result.unionOrderBy.addAll(unionOrderBy); - - - - result.unionSeek.addAll(unionSeek); - result.unionSeekBefore = unionSeekBefore; - result.unionLimit.from(unionLimit); - - return result; - } - - /** - * Copy all clauses into a new query. - */ private final SelectQueryImpl copy(Function, ? extends SelectQueryImpl> finisher) { - return finisher.apply(copyAfterWhere(copyToWhere(new SelectQueryImpl<>(configuration(), with)))); + return finisher.apply(copyTo(CopyClause.END, new SelectQueryImpl<>(configuration(), with))); } - /** - * Nest all clauses up to the WHERE clause in a derived table. - */ - private final SelectQueryImpl nestToWhere(Function, ? extends SelectQueryImpl> nestedFinisher) { + private final SelectQueryImpl nestTo(CopyClause clause, Function, ? extends SelectQueryImpl> nestedFinisher) { SelectQueryImpl result = new SelectQueryImpl<>(configuration(), with); - // Nesting is only required if we have clauses after WHERE - if (stopsAtWhere()) - return nestedFinisher.apply(copyToWhere(result)); + // Nesting is only required if we have clauses after the requested clause + if (stopsAt(clause)) + return nestedFinisher.apply(copyTo(clause, result)); else - return copyAfterWhere(nest(result, copyToWhere(new SelectQueryImpl<>(configuration(), null)), nestedFinisher)); - } - - /** - * Nest all clauses up to the QUALIFY clause in a derived table. - */ - private final SelectQueryImpl nestToQualify(Function, ? extends SelectQueryImpl> nestedFinisher) { - SelectQueryImpl result = new SelectQueryImpl<>(configuration(), with); - - // Nesting is only required if we have clauses after QUALIFY - if (stopsAtQualify()) - return nestedFinisher.apply(copyToQualify(result)); - else - return copyAfterQualify(nest(result, copyToQualify(new SelectQueryImpl<>(configuration(), null)), nestedFinisher)); + return copyAfter(clause, nest(result, copyTo(clause, new SelectQueryImpl<>(configuration(), null)), nestedFinisher)); } private final SelectQueryImpl nest(SelectQueryImpl result, SelectQueryImpl nested, Function, ? extends SelectQueryImpl> nestedFinisher) { @@ -1413,6 +1380,14 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + + + + + + +