[jOOQ/jOOQ#15551] Fix UDT type casts of bind values

This commit is contained in:
Lukas Eder 2023-09-06 16:05:04 +02:00
parent 73da24c17c
commit 30b198ea77
3 changed files with 39 additions and 14 deletions

View File

@ -163,6 +163,8 @@ import static org.jooq.impl.Tools.convertHexToBytes;
import static org.jooq.impl.Tools.emulateMultiset;
import static org.jooq.impl.Tools.enums;
// ...
import static org.jooq.impl.Tools.getMappedTable;
import static org.jooq.impl.Tools.getMappedUDT;
import static org.jooq.impl.Tools.getMappedUDTName;
import static org.jooq.impl.Tools.getRecordQualifier;
import static org.jooq.impl.Tools.isEmpty;
@ -170,6 +172,7 @@ import static org.jooq.impl.Tools.map;
import static org.jooq.impl.Tools.needsBackslashEscaping;
import static org.jooq.impl.Tools.newRecord;
import static org.jooq.impl.Tools.uncoerce;
import static org.jooq.tools.StringUtils.defaultIfNull;
import static org.jooq.tools.StringUtils.leftPad;
import static org.jooq.tools.jdbc.JDBCUtils.safeFree;
import static org.jooq.tools.jdbc.JDBCUtils.wasNull;
@ -258,6 +261,7 @@ import org.jooq.Param;
// ...
import org.jooq.QualifiedRecord;
import org.jooq.Record;
import org.jooq.RecordQualifier;
import org.jooq.RenderContext;
import org.jooq.Result;
import org.jooq.Row;
@ -4047,12 +4051,16 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// -------------------------------------------------------------------------
final void pgRenderRecordCast(Context<?> ctx) {
if (dataType instanceof UDTDataType<?> u)
ctx.visit(u.udt);
else if (dataType instanceof TableDataType<?> t)
ctx.visit(t.table);
else if (dataType.isUDT())
ctx.visit(getRecordQualifier(dataType));
if (dataType instanceof UDTDataType<?> u) {
ctx.visit(defaultIfNull(getMappedUDT(ctx, u.udt), u.udt));
}
else if (dataType instanceof TableDataType<?> t) {
ctx.visit(defaultIfNull(getMappedTable(ctx, t.table), t.table));
}
else if (dataType.isUDT()) {
RecordQualifier<?> q = getRecordQualifier(dataType);
ctx.visit(defaultIfNull(Tools.getMappedQualifier(ctx, q), q));
}
else
ctx.visit(dataType.getQualifiedName());
}

View File

@ -43,6 +43,7 @@ import static org.jooq.impl.DSL.val;
import static org.jooq.impl.DefaultBinding.DefaultRecordBinding.REQUIRE_RECORD_CAST;
import static org.jooq.impl.Keywords.K_NULL;
import static org.jooq.impl.Keywords.K_ROW;
import static org.jooq.impl.Tools.getMappedQualifier;
import static org.jooq.impl.Tools.getMappedUDTName;
import org.jooq.BindContext;
@ -154,7 +155,7 @@ final class QualifiedRecordConstant<R extends QualifiedRecord<R>> extends Abstra
break;
default: {
c.visit(qualifier);
c.visit(mappedQualifier(ctx));
break;
}
}
@ -173,7 +174,7 @@ final class QualifiedRecordConstant<R extends QualifiedRecord<R>> extends Abstra
},
// [#13174] Need to cast inline UDT ROW expressions to the UDT type
c -> c.visit(qualifier),
c -> c.visit(mappedQualifier(ctx)),
() -> REQUIRE_RECORD_CAST.contains(ctx.dialect())
@ -181,6 +182,11 @@ final class QualifiedRecordConstant<R extends QualifiedRecord<R>> extends Abstra
);
}
private final RecordQualifier<?> mappedQualifier(RenderContext ctx) {
RecordQualifier<?> mapped = getMappedQualifier(ctx, qualifier);
return mapped != null ? mapped : qualifier;
}
@Deprecated
private final String getInlineConstructor(RenderContext ctx) {
switch (ctx.family()) {

View File

@ -3676,6 +3676,20 @@ final class Tools {
return udt;
}
/**
* Map a {@link UDT} according to the configured {@link org.jooq.SchemaMapping}
*/
static final RecordQualifier<?> getMappedQualifier(Scope scope, RecordQualifier<?> qualifier) {
if (scope != null) {
if (qualifier instanceof UDT<?> u)
return scope.configuration().schemaMapping().map(u);
else if (qualifier instanceof Table<?> t)
return scope.configuration().schemaMapping().map(t);
}
return qualifier;
}
/**
* Map an {@link QualifiedRecord} according to the configured
* {@link org.jooq.SchemaMapping}
@ -3691,13 +3705,10 @@ final class Tools {
*/
static final String getMappedUDTName(Scope scope, QualifiedRecord<?> record) {
RecordQualifier<?> udt = record.getQualifier();
RecordQualifier<?> mappedUDT = getMappedQualifier(scope, udt);
if (udt instanceof UDT<?> u) {
UDT<?> u2 = getMappedUDT(scope, u);
if (u2 != null && u2 != u)
return u2.getQualifiedName().unquotedName().toString();
}
if (mappedUDT != null && mappedUDT != udt)
return mappedUDT.getQualifiedName().unquotedName().toString();
Schema mapped = getMappedSchema(scope, udt.getSchema());
StringBuilder sb = new StringBuilder();