[jOOQ/jOOQ#10992] Wrong SQL generated when outer and correlated subquery share implicit join path

This commit is contained in:
Lukas Eder 2020-11-20 17:39:23 +01:00
parent e4aa7c1eed
commit 7ae2bb1b8e
5 changed files with 33 additions and 9 deletions

View File

@ -181,11 +181,23 @@ public interface Context<C extends Context<C>> extends Scope {
C scopeMarkStart(QueryPart part);
/**
* Register a "special" query part in the scope.
* Register a "special" query part in the scope, reusing the object from a
* higher scope, if available.
*/
@NotNull
C scopeRegister(QueryPart part);
/**
* Register a "special" query part in the scope, allowing to force
* registering the object in the new scope, if a higher scope already has
* the object.
* <p>
* [#10992] This is necessary to allow for hiding identifiers from nested
* scopes.
*/
@NotNull
C scopeRegister(QueryPart part, boolean forceNew);
/**
* Mark the end of a scoped query part.
*/

View File

@ -572,7 +572,12 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
}
@Override
public /* non-final */ C scopeRegister(QueryPart part) {
public final C scopeRegister(QueryPart part) {
return scopeRegister(part, false);
}
@Override
public /* non-final */ C scopeRegister(QueryPart part, boolean forceNew) {
return (C) this;
}

View File

@ -189,7 +189,7 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
}
@Override
public RenderContext scopeRegister(QueryPart part) {
public RenderContext scopeRegister(QueryPart part, boolean forceNew) {
if (scopeStack.inScope()) {
if (part instanceof TableImpl) {
Table<?> root = (Table<?>) part;
@ -201,7 +201,10 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
root = child;
}
ScopeStackElement e = scopeStack.getOrCreate(root);
ScopeStackElement e = forceNew
? scopeStack.create(root)
: scopeStack.getOrCreate(root);
if (e.joinNode == null)
e.joinNode = new JoinNode(root);

View File

@ -158,12 +158,16 @@ final class ScopeStack<K, V> implements Iterable<V> {
final V getOrCreate(K key) {
List<V> list = list(key);
V result = get0(list);
return result != null ? result : create0(list);
}
if (result == null) {
result = constructor.create(scopeLevel);
set0(list, result);
}
final V create(K key) {
return create0(list(key));
}
private final V create0(List<V> list) {
V result = constructor.create(scopeLevel);
set0(list, result);
return result;
}

View File

@ -1537,7 +1537,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
registerTable(context, ((JoinTable) table).rhs);
}
else if (table instanceof TableImpl)
context.scopeRegister(table);
context.scopeRegister(table, true);
}
private final void pushWindow(Context<?> context) {