[jOOQ/jOOQ#15632] Support InlineDerivedTables in UPDATE

This commit is contained in:
Lukas Eder 2023-09-25 10:42:06 +02:00
parent 54d663bcba
commit ef2b95eb46
6 changed files with 35 additions and 48 deletions

View File

@ -1184,14 +1184,14 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
}
static class JoinNode {
final Configuration configuration;
final Context<?> ctx;
final Table<?> table;
final Map<ForeignKey<?, ?>, JoinNode> pathsToOne;
final Map<InverseForeignKey<?, ?>, JoinNode> pathsToMany;
int references;
JoinNode(Configuration configuration, Table<?> table) {
this.configuration = configuration;
JoinNode(Context<?> ctx, Table<?> table) {
this.ctx = ctx;
this.table = table;
this.pathsToOne = new LinkedHashMap<>();
this.pathsToMany = new LinkedHashMap<>();
@ -1215,7 +1215,6 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
for (Entry<ForeignKey<?, ?>, JoinNode> e : pathsToOne.entrySet()) {
Table<?> t = e.getValue().joinTree();
@ -1265,7 +1264,7 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
}
private final JoinType joinType(JoinType onDefault) {
switch (defaultIfNull(Tools.settings(configuration).getRenderImplicitJoinType(), RenderImplicitJoinType.DEFAULT)) {
switch (defaultIfNull(Tools.settings(ctx.configuration()).getRenderImplicitJoinType(), RenderImplicitJoinType.DEFAULT)) {
case INNER_JOIN:
return JOIN;
case LEFT_JOIN:

View File

@ -152,6 +152,7 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
qualifySchema(context.qualifySchema());
quote(context.quote());
castMode(context.castMode());
topLevelForLanguageContext(context.topLevelForLanguageContext());
if (copyLocalState) {
data().putAll(context.data());
@ -248,16 +249,16 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
: scopeStack.getOrCreate(root);
if (e.joinNode == null)
e.joinNode = new JoinNode(configuration(), root);
e.joinNode = new JoinNode(this, root);
JoinNode node = e.joinNode;
for (int i = tables.size() - 1; i >= 0; i--) {
TableImpl<?> t = tables.get(i);
if (t.childPath != null)
node = node.pathsToOne.computeIfAbsent(t.childPath, k -> new JoinNode(configuration(), t));
node = node.pathsToOne.computeIfAbsent(t.childPath, k -> new JoinNode(this, t));
else
node = node.pathsToMany.computeIfAbsent(t.parentPath, k -> new JoinNode(configuration(), t));
node = node.pathsToMany.computeIfAbsent(t.parentPath, k -> new JoinNode(this, t));
if (i == 0)
node.references++;

View File

@ -42,6 +42,8 @@ import static org.jooq.impl.DSL.selectFrom;
import static org.jooq.impl.DSL.table;
import org.jooq.Condition;
import org.jooq.Context;
// ...
import org.jooq.QueryPart;
import org.jooq.Record;
// ...
@ -68,6 +70,21 @@ final class InlineDerivedTable<R extends Record> extends DerivedTable<R> {
this.condition = condition;
}
static final <R extends Record> Table<R> inlineDerivedTable(Context<?> ctx, Table<R> t) {
return InlineDerivedTable.derivedTable(t);
}
static final <R extends Record> Table<R> derivedTable(Table<R> t) {
if (t instanceof InlineDerivedTable<R> i) {
return i;

View File

@ -73,25 +73,6 @@ package org.jooq.impl;

View File

@ -2783,18 +2783,8 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
return r;
}
private static final <R extends Record> Table<R> inlineDerivedTable(Context<?> ctx, Table<R> t) {
return InlineDerivedTable.derivedTable(t);
}
private static final boolean hasInlineDerivedTables(Context<?> ctx, Table<?> t) {
return inlineDerivedTable(ctx, t) != null
return InlineDerivedTable.inlineDerivedTable(ctx, t) != null
|| t instanceof JoinTable && (hasInlineDerivedTables(ctx, ((JoinTable<?>) t).lhs) || hasInlineDerivedTables(ctx, ((JoinTable<?>) t).rhs));
}
@ -2853,7 +2843,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
TableList result,
ConditionProviderImpl where
) {
Table<?> t = inlineDerivedTable(ctx, table);
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
if (t != null) {
if (t instanceof InlineDerivedTable<?> i) {
@ -2875,7 +2865,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
ConditionProviderImpl where,
boolean keepDerivedTable
) {
Table<?> t = inlineDerivedTable(ctx, table);
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
if (t != null) {
if (t instanceof InlineDerivedTable<?> i) {

View File

@ -564,14 +564,13 @@ implements
@Override
public final void accept(Context<?> ctx) {
accept0(ctx);
// [#2682] [#15632] Apply inline derived tables to the target table (TODO: Apply also to USING, etc.)
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table(ctx));
if (t instanceof InlineDerivedTable<?> i) {
copy(d -> d.addConditions(i.condition), i.table).accept0(ctx);
}
else
accept0(ctx);
}
@Override