[jOOQ/jOOQ#10992] Wrong SQL generated when outer and correlated subquery share implicit join path
This commit is contained in:
parent
e4aa7c1eed
commit
7ae2bb1b8e
@ -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.
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user