[jOOQ/jOOQ#15936] De-duplicate join/path correlation predicates
There are some edge cases where duplicate predicates are being generated from both the join tree (or table lists) and the path correlations. It's worth investigating why this happens rather than removing the duplicates with a Set, but for now this works.
This commit is contained in:
parent
70187dbee8
commit
7ce935bbb5
@ -264,6 +264,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -271,6 +272,7 @@ import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jooq.Asterisk;
|
||||
import org.jooq.Clause;
|
||||
@ -2983,19 +2985,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
Table<?> t0 = result.get(i);
|
||||
Table<?> t1 = prependPathJoins(ctx, where, t0, CROSS_JOIN);
|
||||
|
||||
// [#15936] If join tree leaves contain paths, generate the path correlation predicate here
|
||||
// [#15967] But only if they're in scope, and not in the current scope
|
||||
traverseJoins(t1, where, null, l -> true, r -> true, null,
|
||||
(w, t) -> {
|
||||
if (TableImpl.path(t) != null && t instanceof TableImpl<?> ti) {
|
||||
if (ctx.inScope(ti.path) && !ctx.inCurrentScope(ti.path))
|
||||
w.addConditions(ti.pathCondition());
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
);
|
||||
|
||||
if (t0 != t1)
|
||||
result.set(i, t1);
|
||||
}
|
||||
@ -4556,31 +4545,49 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
static final void addPathConditions(Context<?> ctx, ConditionProviderImpl where0, TableList tablelist) {
|
||||
|
||||
// [#15936] Avoid duplicate conditions produced by join tree and path correlation
|
||||
// TODO: This de-duplication shouldn't be necessary: find the cause.
|
||||
Set<Condition> set = new LinkedHashSet<>();
|
||||
|
||||
// [#13639] Add JOIN predicates generated by path expressions in FROM clause.
|
||||
for (Table<?> t : tablelist)
|
||||
addPathConditions(ctx, where0, t);
|
||||
addPathConditions(ctx, set, t);
|
||||
|
||||
traverseJoins(
|
||||
tablelist, null, null,
|
||||
tablelist, set, null,
|
||||
t -> {
|
||||
if (t instanceof CrossJoin j) {
|
||||
addPathConditions(ctx, where0, j.lhs);
|
||||
addPathConditions(ctx, where0, j.rhs);
|
||||
addPathConditions(ctx, set, j.lhs);
|
||||
addPathConditions(ctx, set, j.rhs);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
null, null, null
|
||||
null, null,
|
||||
|
||||
// [#15936] If join tree leaves contain paths, generate the path correlation predicate here
|
||||
// [#15967] But only if they're in scope, and not in the current scope, in a subquery
|
||||
!ctx.subquery() ? null :
|
||||
(w, t) -> {
|
||||
addPathConditions(ctx, w, t, ti -> !ctx.inCurrentScope(ti.path));
|
||||
return w;
|
||||
}
|
||||
);
|
||||
|
||||
where0.addConditions(set);
|
||||
}
|
||||
|
||||
private static final void addPathConditions(Context<?> ctx, ConditionProviderImpl result, Table<?> t) {
|
||||
private static final void addPathConditions(Context<?> ctx, Collection<Condition> result, Table<?> t) {
|
||||
addPathConditions(ctx, result, t, null);
|
||||
}
|
||||
|
||||
private static final void addPathConditions(Context<?> ctx, Collection<Condition> result, Table<?> t, Predicate<? super TableImpl<?>> predicate) {
|
||||
if (t instanceof TableImpl<?> ti) {
|
||||
|
||||
// [#14985] [#15967] In some edge cases, users may have chosen to use a path in the FROM
|
||||
// clause, whose path root isn't in scope. In that case, we must ignore
|
||||
// the path.
|
||||
if (ti.path != null && ctx.inScope(ti.path))
|
||||
result.addConditions(ti.pathCondition());
|
||||
if (ti.path != null && ctx.inScope(ti.path) && (predicate == null || predicate.test(ti)))
|
||||
result.add(ti.pathCondition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user