[jOOQ/jOOQ#2682] [jOOQ/jOOQ#15632] Support DELETE .. USING
This commit is contained in:
parent
6ef4abdbbb
commit
fa8a665b05
@ -82,6 +82,7 @@ import static org.jooq.impl.DSL.noCondition;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.trueCondition;
|
||||
import static org.jooq.impl.InlineDerivedTable.transformInlineDerivedTables;
|
||||
import static org.jooq.impl.Internal.hash;
|
||||
import static org.jooq.impl.Keywords.K_DELETE;
|
||||
import static org.jooq.impl.Keywords.K_FROM;
|
||||
@ -253,11 +254,28 @@ implements
|
||||
public final void accept(Context<?> ctx) {
|
||||
ctx.scopeStart(this);
|
||||
|
||||
// [#2682] [#15632] Apply inline derived tables to the target table (TODO: Apply also to USING, etc.)
|
||||
// [#2682] [#15632] Apply inline derived tables to the target table
|
||||
// [#15632] TODO: Check if this behaves correctly with aliases
|
||||
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table(ctx));
|
||||
if (t instanceof InlineDerivedTable<?> i) {
|
||||
copy(d -> d.addConditions(i.condition), i.table).accept0(ctx);
|
||||
Table<?> t = table(ctx);
|
||||
Table<?> i = InlineDerivedTable.inlineDerivedTable(ctx, t);
|
||||
InlineDerivedTable<?> j = i instanceof InlineDerivedTable ? (InlineDerivedTable<?>) i : null;
|
||||
ConditionProviderImpl where = new ConditionProviderImpl();
|
||||
TableList u = transformInlineDerivedTables(ctx, using, where);
|
||||
|
||||
if (j != null || u != using) {
|
||||
copy(
|
||||
d -> {
|
||||
if (j != null) {
|
||||
d.addConditions(j.condition);
|
||||
}
|
||||
if (u != using) {
|
||||
d.addConditions(where);
|
||||
d.using.clear();
|
||||
d.using.addAll(u);
|
||||
}
|
||||
},
|
||||
(Table<?>) (j != null ? j.table : t)
|
||||
).accept0(ctx);
|
||||
}
|
||||
else
|
||||
accept0(ctx);
|
||||
@ -437,11 +455,11 @@ implements
|
||||
// XXX: Query Object Model
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
final DeleteQueryImpl<R> copy(Consumer<? super DeleteQueryImpl<R>> finisher) {
|
||||
final DeleteQueryImpl<R> copy(Consumer<? super DeleteQueryImpl<?>> finisher) {
|
||||
return copy(finisher, table);
|
||||
}
|
||||
|
||||
final <O extends Record> DeleteQueryImpl<O> copy(Consumer<? super DeleteQueryImpl<O>> finisher, Table<O> t) {
|
||||
final <O extends Record> DeleteQueryImpl<O> copy(Consumer<? super DeleteQueryImpl<?>> finisher, Table<O> t) {
|
||||
DeleteQueryImpl<O> r = new DeleteQueryImpl<>(configuration(), with, t);
|
||||
r.using.addAll(using);
|
||||
r.condition.addConditions(extractCondition(condition));
|
||||
|
||||
@ -40,6 +40,7 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.selectFrom;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
import static org.jooq.impl.Tools.anyMatch;
|
||||
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Context;
|
||||
@ -70,6 +71,121 @@ final class InlineDerivedTable<R extends Record> extends DerivedTable<R> {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
static final boolean hasInlineDerivedTables(Context<?> ctx, Table<?> t) {
|
||||
return InlineDerivedTable.inlineDerivedTable(ctx, t) != null
|
||||
|| t instanceof JoinTable && (hasInlineDerivedTables(ctx, ((JoinTable<?>) t).lhs) || hasInlineDerivedTables(ctx, ((JoinTable<?>) t).rhs));
|
||||
}
|
||||
|
||||
static final boolean hasInlineDerivedTables(Context<?> ctx, TableList tablelist) {
|
||||
return anyMatch(tablelist, t -> hasInlineDerivedTables(ctx, t));
|
||||
}
|
||||
|
||||
static final TableList transformInlineDerivedTables(Context<?> ctx, TableList tablelist, ConditionProviderImpl where) {
|
||||
if (!hasInlineDerivedTables(ctx, tablelist))
|
||||
return tablelist;
|
||||
|
||||
TableList result = new TableList();
|
||||
|
||||
for (Table<?> table : tablelist)
|
||||
transformInlineDerivedTable0(ctx, table, result, where);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static final void transformInlineDerivedTable0(
|
||||
Context<?> ctx,
|
||||
Table<?> table,
|
||||
TableList result,
|
||||
ConditionProviderImpl where
|
||||
) {
|
||||
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
|
||||
|
||||
if (t != null) {
|
||||
if (t instanceof InlineDerivedTable<?> i) {
|
||||
result.add(i.table);
|
||||
where.addConditions(i.condition);
|
||||
}
|
||||
else
|
||||
result.add(t);
|
||||
}
|
||||
else if (table instanceof JoinTable)
|
||||
result.add(transformInlineDerivedTables0(ctx, table, where, false));
|
||||
else
|
||||
result.add(table);
|
||||
}
|
||||
|
||||
static final Table<?> transformInlineDerivedTables0(
|
||||
Context<?> ctx,
|
||||
Table<?> table,
|
||||
ConditionProviderImpl where,
|
||||
boolean keepDerivedTable
|
||||
) {
|
||||
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
|
||||
|
||||
if (t != null) {
|
||||
if (t instanceof InlineDerivedTable<?> i) {
|
||||
if (keepDerivedTable) {
|
||||
|
||||
// [#2682] An explicit path join that produces an InlineDerivedTable (e.g. due to a Policy)
|
||||
if (TableImpl.path(i.table) != null) {
|
||||
where.addConditions(((TableImpl<?>) i.table).pathCondition());
|
||||
return selectFrom(Tools.unwrap(i.table).as(i.table)).asTable(i.table);
|
||||
}
|
||||
else
|
||||
return i.query().asTable(i.table);
|
||||
}
|
||||
|
||||
where.addConditions(i.condition);
|
||||
return i.table;
|
||||
}
|
||||
else
|
||||
return t;
|
||||
}
|
||||
else if (table instanceof JoinTable<?> j) {
|
||||
Table<?> lhs;
|
||||
Table<?> rhs;
|
||||
ConditionProviderImpl w = new ConditionProviderImpl();
|
||||
|
||||
switch (j.type) {
|
||||
case LEFT_OUTER_JOIN:
|
||||
case LEFT_ANTI_JOIN:
|
||||
case LEFT_SEMI_JOIN:
|
||||
case STRAIGHT_JOIN:
|
||||
case CROSS_APPLY:
|
||||
case OUTER_APPLY:
|
||||
case NATURAL_LEFT_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, where, keepDerivedTable);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, w, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case RIGHT_OUTER_JOIN:
|
||||
case NATURAL_RIGHT_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, w, true);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, where, keepDerivedTable);
|
||||
break;
|
||||
}
|
||||
|
||||
case FULL_OUTER_JOIN:
|
||||
case NATURAL_FULL_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, w, true);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, w, true);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, where, keepDerivedTable);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, where, keepDerivedTable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return j.transform(lhs, rhs, w.hasWhere() ? w : j.condition);
|
||||
}
|
||||
else
|
||||
return table;
|
||||
}
|
||||
|
||||
static final <R extends Record> Table<R> inlineDerivedTable(Context<?> ctx, Table<R> t) {
|
||||
|
||||
|
||||
|
||||
@ -163,6 +163,7 @@ import static org.jooq.impl.DSL.unquotedName;
|
||||
import static org.jooq.impl.DSL.xmlagg;
|
||||
import static org.jooq.impl.DSL.xmlattributes;
|
||||
import static org.jooq.impl.DSL.xmlelement;
|
||||
import static org.jooq.impl.InlineDerivedTable.transformInlineDerivedTables;
|
||||
import static org.jooq.impl.Internal.isub;
|
||||
import static org.jooq.impl.JSONArrayAgg.EMULATE_WITH_GROUP_CONCAT;
|
||||
import static org.jooq.impl.JSONArrayAgg.patchOracleArrayAggBug;
|
||||
@ -2784,14 +2785,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
return r;
|
||||
}
|
||||
|
||||
private static final boolean hasInlineDerivedTables(Context<?> ctx, Table<?> t) {
|
||||
return InlineDerivedTable.inlineDerivedTable(ctx, t) != null
|
||||
|| t instanceof JoinTable && (hasInlineDerivedTables(ctx, ((JoinTable<?>) t).lhs) || hasInlineDerivedTables(ctx, ((JoinTable<?>) t).rhs));
|
||||
}
|
||||
|
||||
private static final boolean hasInlineDerivedTables(Context<?> ctx, TableList tablelist) {
|
||||
return anyMatch(tablelist, t -> hasInlineDerivedTables(ctx, t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2826,117 +2819,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
|
||||
|
||||
|
||||
|
||||
private static final TableList transformInlineDerivedTables(Context<?> ctx, TableList tablelist, ConditionProviderImpl where) {
|
||||
if (!hasInlineDerivedTables(ctx, tablelist))
|
||||
return tablelist;
|
||||
|
||||
TableList result = new TableList();
|
||||
|
||||
for (Table<?> table : tablelist)
|
||||
transformInlineDerivedTable0(ctx, table, result, where);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final void transformInlineDerivedTable0(
|
||||
Context<?> ctx,
|
||||
Table<?> table,
|
||||
TableList result,
|
||||
ConditionProviderImpl where
|
||||
) {
|
||||
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
|
||||
|
||||
if (t != null) {
|
||||
if (t instanceof InlineDerivedTable<?> i) {
|
||||
result.add(i.table);
|
||||
where.addConditions(i.condition);
|
||||
}
|
||||
else
|
||||
result.add(t);
|
||||
}
|
||||
else if (table instanceof JoinTable)
|
||||
result.add(transformInlineDerivedTables0(ctx, table, where, false));
|
||||
else
|
||||
result.add(table);
|
||||
}
|
||||
|
||||
private static final Table<?> transformInlineDerivedTables0(
|
||||
Context<?> ctx,
|
||||
Table<?> table,
|
||||
ConditionProviderImpl where,
|
||||
boolean keepDerivedTable
|
||||
) {
|
||||
Table<?> t = InlineDerivedTable.inlineDerivedTable(ctx, table);
|
||||
|
||||
if (t != null) {
|
||||
if (t instanceof InlineDerivedTable<?> i) {
|
||||
if (keepDerivedTable) {
|
||||
|
||||
// [#2682] An explicit path join that produces an InlineDerivedTable (e.g. due to a Policy)
|
||||
if (TableImpl.path(i.table) != null) {
|
||||
where.addConditions(((TableImpl<?>) i.table).pathCondition());
|
||||
return selectFrom(Tools.unwrap(i.table).as(i.table)).asTable(i.table);
|
||||
}
|
||||
else
|
||||
return i.query().asTable(i.table);
|
||||
}
|
||||
|
||||
where.addConditions(i.condition);
|
||||
return i.table;
|
||||
}
|
||||
else
|
||||
return t;
|
||||
}
|
||||
else if (table instanceof JoinTable<?> j) {
|
||||
Table<?> lhs;
|
||||
Table<?> rhs;
|
||||
ConditionProviderImpl w = new ConditionProviderImpl();
|
||||
|
||||
switch (j.type) {
|
||||
case LEFT_OUTER_JOIN:
|
||||
case LEFT_ANTI_JOIN:
|
||||
case LEFT_SEMI_JOIN:
|
||||
case STRAIGHT_JOIN:
|
||||
case CROSS_APPLY:
|
||||
case OUTER_APPLY:
|
||||
case NATURAL_LEFT_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, where, keepDerivedTable);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, w, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case RIGHT_OUTER_JOIN:
|
||||
case NATURAL_RIGHT_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, w, true);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, where, keepDerivedTable);
|
||||
break;
|
||||
}
|
||||
|
||||
case FULL_OUTER_JOIN:
|
||||
case NATURAL_FULL_OUTER_JOIN: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, w, true);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, w, true);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
lhs = transformInlineDerivedTables0(ctx, j.lhs, where, keepDerivedTable);
|
||||
rhs = transformInlineDerivedTables0(ctx, j.rhs, where, keepDerivedTable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return j.transform(lhs, rhs, w.hasWhere() ? w : j.condition);
|
||||
}
|
||||
else
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user