[jOOQ/jOOQ#15820] Incorrect query generated when combining SEEK with

GROUP BY
This commit is contained in:
Lukas Eder 2023-11-13 10:29:09 +01:00
parent 8a9b202618
commit 3433145157

View File

@ -2488,7 +2488,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
;
List<Condition> semiAntiJoinPredicates = null;
@ -2606,7 +2605,8 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
// --------------------------
context.start(SELECT_GROUP_BY);
if (!getGroupBy().isEmpty() || getHaving().hasWhere() && NO_IMPLICIT_GROUP_BY_ON_HAVING.contains(context.dialect())) {
ConditionProviderImpl having0 = getHaving(context);
if (!getGroupBy().isEmpty() || having0.hasWhere() && NO_IMPLICIT_GROUP_BY_ON_HAVING.contains(context.dialect())) {
context.formatSeparator()
.visit(K_GROUP_BY);
@ -2641,11 +2641,11 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
// -------------
context.start(SELECT_HAVING);
if (getHaving().hasWhere())
if (having0.hasWhere())
context.formatSeparator()
.visit(K_HAVING)
.sql(' ')
.visit(getHaving());
.visit(having0);
context.end(SELECT_HAVING);
@ -4272,7 +4272,8 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
// - There is a SEEK clause (obvious case)
// - There are no unions (union is nested in derived table
// and SEEK predicate is applied outside). See [#7459]
if (!getOrderBy().isEmpty() && !getSeek().isEmpty() && unionOp.isEmpty())
// [#15820] We're not grouping
if (!isGrouping() && !getOrderBy().isEmpty() && !getSeek().isEmpty() && unionOp.isEmpty())
result.addConditions(getSeekCondition(ctx));
// [#13639] Add JOIN predicates generated by path expressions in FROM clause.
@ -4405,12 +4406,32 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
final boolean isGrouping() {
// [#15820] TODO: The presence of any aggregate function also implies at least GROUP BY ()
return !groupBy.isEmpty() || having.hasWhere();
}
final GroupFieldList getGroupBy() {
return groupBy;
}
final ConditionProviderImpl getHaving() {
return having;
final ConditionProviderImpl getHaving(Context<?> ctx) {
ConditionProviderImpl result = new ConditionProviderImpl();
if (having.hasWhere())
result.addConditions(having.getWhere());
// Apply SEEK predicates in the WHERE clause only if:
// - There is an ORDER BY clause (SEEK is non-deterministic)
// - There is a SEEK clause (obvious case)
// - There are no unions (union is nested in derived table
// and SEEK predicate is applied outside). See [#7459]
// [#15820] We're not grouping
if (isGrouping() && !getOrderBy().isEmpty() && !getSeek().isEmpty() && unionOp.isEmpty())
result.addConditions(getSeekCondition(ctx));
return result;
}
final ConditionProviderImpl getQualify() {
@ -4646,32 +4667,32 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
@Override
public final void addHaving(Condition conditions) {
getHaving().addConditions(conditions);
having.addConditions(conditions);
}
@Override
public final void addHaving(Condition... conditions) {
getHaving().addConditions(conditions);
having.addConditions(conditions);
}
@Override
public final void addHaving(Collection<? extends Condition> conditions) {
getHaving().addConditions(conditions);
having.addConditions(conditions);
}
@Override
public final void addHaving(Operator operator, Condition conditions) {
getHaving().addConditions(operator, conditions);
having.addConditions(operator, conditions);
}
@Override
public final void addHaving(Operator operator, Condition... conditions) {
getHaving().addConditions(operator, conditions);
having.addConditions(operator, conditions);
}
@Override
public final void addHaving(Operator operator, Collection<? extends Condition> conditions) {
getHaving().addConditions(operator, conditions);
having.addConditions(operator, conditions);
}
@Override