[jOOQ/jOOQ#2682] [jOOQ/jOOQ#15632] Make SchemaMapping work

SchemaMapping may rename a table in the inline derived table's condition, so the inline derived table alias needs to take this into account as well.

There are probably quite a few related bugs in jOOQ, which aren't showing in existing integration tests yet...
This commit is contained in:
Lukas Eder 2023-09-26 16:29:47 +02:00
parent 7101c4b371
commit e46eabf1cb
2 changed files with 23 additions and 5 deletions

View File

@ -41,6 +41,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 static org.jooq.tools.StringUtils.defaultIfNull;
import org.jooq.Condition;
import org.jooq.Context;
@ -126,13 +127,17 @@ final class InlineDerivedTable<R extends Record> extends DerivedTable<R> {
if (t instanceof InlineDerivedTable<?> i) {
if (keepDerivedTable) {
// [#15632] SchemaMapping could produce a different table than the one contained
// in the inline derived table specification, and the alias must reflect that
Table<?> m = DSL.table(defaultIfNull(ctx.dsl().map(i.table), i.table).getUnqualifiedName());
// [#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);
return selectFrom(Tools.unwrap(i.table).as(m)).asTable(m);
}
else
return i.query().asTable(i.table);
return i.query().asTable(m);
}
where.addConditions(i.condition);

View File

@ -104,6 +104,7 @@ import static org.jooq.impl.Tools.BooleanDataKey.DATA_INSERT_SELECT;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_INSERT_SELECT_WITHOUT_INSERT_COLUMN_LIST;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_MANDATORY_WHERE_CLAUSE;
import static org.jooq.impl.Tools.SimpleDataKey.DATA_ON_DUPLICATE_KEY_WHERE;
import static org.jooq.tools.StringUtils.defaultIfNull;
import java.util.ArrayList;
import java.util.Arrays;
@ -115,6 +116,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.Set;
@ -383,12 +385,23 @@ implements
if (t instanceof InlineDerivedTable<?> i) {
copy(
d -> {
if (!d.insertMaps.values.isEmpty())
if (!d.insertMaps.values.isEmpty()) {
// [#15632] SchemaMapping could produce a different table than the one contained
// in the inline derived table specification, and the alias must reflect that
Table<?> m = DSL.table(defaultIfNull(ctx.dsl().map(i.table), i.table).getUnqualifiedName());
d.select =
selectFrom(
(d.select != null ? d.select : d.insertMaps.insertSelect(ctx, null))
.asTable(i.table, d.insertMaps.keysFlattened(ctx, GeneratorStatementType.INSERT)))
.where(CustomCondition.of(c1 -> c1.qualifySchema(false, c2 -> c2.visit(i.condition))));
.asTable(m, d.insertMaps.keysFlattened(ctx, GeneratorStatementType.INSERT)))
.where(CustomCondition.of(c1 -> c1
// [#15632] Map the original table reference to the derived table alias
// to prevent schema mapping in the condition.
.scopeRegister(i.table, false, m).visit(i.condition)
));
}
},
i.table
).accept0(ctx);