[jOOQ/jOOQ#7863] Fixed binding of %ROWTYPE IN and OUT parameters
Previous commits fixed TABLE OF X%ROWTYPE bindings, but the X%ROWTYPE emulation was not implemented yet. Those can't be bound using ordinary SQLData API, it seems.
This commit is contained in:
parent
32c08aafe1
commit
d210d5f35d
@ -84,9 +84,9 @@ import org.jooq.JSONB;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Nullability;
|
||||
// ...
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.tools.Convert;
|
||||
import org.jooq.types.Interval;
|
||||
@ -374,7 +374,7 @@ abstract class AbstractDataType<T> extends AbstractNamed implements DataType<T>
|
||||
|
||||
else if (EnumType.class.isAssignableFrom(tType))
|
||||
return Types.VARCHAR;
|
||||
else if (UDTRecord.class.isAssignableFrom(tType))
|
||||
else if (QualifiedRecord.class.isAssignableFrom(tType))
|
||||
return Types.STRUCT;
|
||||
else if (Result.class.isAssignableFrom(tType)) {
|
||||
switch (configuration.family()) {
|
||||
@ -648,7 +648,7 @@ abstract class AbstractDataType<T> extends AbstractNamed implements DataType<T>
|
||||
|
||||
@Override
|
||||
public final boolean isUDT() {
|
||||
return UDTRecord.class.isAssignableFrom(tType0());
|
||||
return QualifiedRecord.class.isAssignableFrom(tType0());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -54,9 +54,8 @@ import org.jooq.DataType;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.ParamMode;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
@ -106,8 +105,8 @@ abstract class AbstractParam<T> extends AbstractParamX<T> implements SimpleQuery
|
||||
? paramName
|
||||
|
||||
// [#3707] Protect value.toString call for certain jOOQ types.
|
||||
: value instanceof UDTRecord
|
||||
? ((UDTRecord<?>) value).getUDT().getName()
|
||||
: value instanceof QualifiedRecord
|
||||
? ((QualifiedRecord<?>) value).getQualifier().getName()
|
||||
|
||||
|
||||
|
||||
|
||||
@ -121,8 +121,10 @@ import org.jooq.Package;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.Parameter;
|
||||
// ...
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordQualifier;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Results;
|
||||
@ -132,7 +134,6 @@ import org.jooq.Schema;
|
||||
import org.jooq.Statement;
|
||||
import org.jooq.UDT;
|
||||
import org.jooq.UDTField;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.XMLFormat;
|
||||
import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.exception.ControlFlowSignal;
|
||||
@ -1094,7 +1095,6 @@ public abstract class AbstractRoutine<T> extends AbstractNamed implements Routin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private final void toSQLAssign(RenderContext context) {
|
||||
@ -1470,6 +1470,16 @@ public abstract class AbstractRoutine<T> extends AbstractNamed implements Routin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -129,7 +129,7 @@ final class ArrayTable extends AbstractTable<Record> {
|
||||
// [#1114] [#7863] VARRAY/TABLE of OBJECT have more than one field
|
||||
if (Record.class.isAssignableFrom(arrayType)) {
|
||||
try {
|
||||
Record record = (Record) arrayType.getConstructor().newInstance();
|
||||
Record record = (Record) arrayType.getDeclaredConstructor().newInstance();
|
||||
|
||||
for (Field<?> f : record.fields())
|
||||
result.add(DSL.field(name(alias.last(), f.getName()), f.getDataType()));
|
||||
|
||||
@ -292,6 +292,7 @@ import org.jooq.Parameter;
|
||||
import org.jooq.PlainSQL;
|
||||
import org.jooq.Privilege;
|
||||
// ...
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.QuantifiedSelect;
|
||||
import org.jooq.Queries;
|
||||
import org.jooq.Query;
|
||||
@ -26608,15 +26609,14 @@ public class DSL {
|
||||
public static <T> Param<T> val(Object value, DataType<T> type) {
|
||||
|
||||
// Advanced data types have dedicated constant types
|
||||
if (value instanceof UDTRecord) {
|
||||
return new UDTConstant((UDTRecord) value);
|
||||
if (value instanceof QualifiedRecord) {
|
||||
return new QualifiedRecordConstant((QualifiedRecord<?>) value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The default behaviour
|
||||
else {
|
||||
T converted = type.convert(value);
|
||||
|
||||
@ -509,7 +509,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
if (QualifiedRecord.class.isAssignableFrom(type)) {
|
||||
Class<QualifiedRecord<?>> t = (Class<QualifiedRecord<?>>) type;
|
||||
result.put(getMappedUDTName(configuration, t), t);
|
||||
QualifiedRecord<?> r = t.getConstructor().newInstance();
|
||||
QualifiedRecord<?> r = t.getDeclaredConstructor().newInstance();
|
||||
for (Field<?> field : r.getQualifier().fields())
|
||||
typeMap(field.getType(), configuration, result);
|
||||
}
|
||||
@ -3531,8 +3531,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
|
||||
@Override
|
||||
final void set0(BindingSetSQLOutputContext<U> ctx, Record value) throws SQLException {
|
||||
if (value instanceof UDTRecord)
|
||||
ctx.output().writeObject((UDTRecord<?>) value);
|
||||
if (value instanceof QualifiedRecord)
|
||||
ctx.output().writeObject((QualifiedRecord<?>) value);
|
||||
else
|
||||
throw new UnsupportedOperationException("Type " + dataType + " is not supported");
|
||||
}
|
||||
|
||||
@ -56,8 +56,8 @@ import org.jooq.ConverterProvider;
|
||||
import org.jooq.EnumType;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.exception.DataTypeException;
|
||||
import org.jooq.tools.Convert;
|
||||
@ -112,7 +112,7 @@ public final class DefaultConverterProvider implements ConverterProvider, Serial
|
||||
|| isXML(tWrapper)
|
||||
|
||||
|| Record.class.isAssignableFrom(tWrapper)
|
||||
|| Struct.class.isAssignableFrom(tWrapper) && UDTRecord.class.isAssignableFrom(uWrapper)
|
||||
|| Struct.class.isAssignableFrom(tWrapper) && QualifiedRecord.class.isAssignableFrom(uWrapper)
|
||||
) {
|
||||
return new AbstractConverter<T, U>(tType, uType) {
|
||||
|
||||
|
||||
@ -76,9 +76,8 @@ import org.jooq.EnumType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Nullability;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.TableRecord;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.exception.MappingException;
|
||||
import org.jooq.exception.SQLDialectNotSupportedException;
|
||||
import org.jooq.types.UByte;
|
||||
@ -691,12 +690,10 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
|
||||
// jOOQ data types are handled here
|
||||
try {
|
||||
if (UDTRecord.class.isAssignableFrom(type))
|
||||
return (DataType<T>) ((UDTRecord<?>) type.newInstance()).getUDT().getDataType();
|
||||
|
||||
// [#7174] PostgreSQL table records can be function argument types
|
||||
else if (TableRecord.class.isAssignableFrom(type))
|
||||
return (DataType<T>) ((TableRecord<?>) type.newInstance()).getTable().getDataType();
|
||||
if (QualifiedRecord.class.isAssignableFrom(type))
|
||||
return (DataType<T>) ((QualifiedRecord<?>) type.getDeclaredConstructor().newInstance()).getQualifier().getDataType();
|
||||
|
||||
|
||||
|
||||
|
||||
@ -45,20 +45,20 @@ import static org.jooq.impl.Keywords.K_ROW;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.exception.SQLDialectNotSupportedException;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class UDTConstant<R extends UDTRecord<R>> extends AbstractParam<R> {
|
||||
final class QualifiedRecordConstant<R extends QualifiedRecord<R>> extends AbstractParam<R> {
|
||||
|
||||
private static final long serialVersionUID = 6807729087019209084L;
|
||||
|
||||
UDTConstant(R value) {
|
||||
super(value, value.getUDT().getDataType());
|
||||
QualifiedRecordConstant(R value) {
|
||||
super(value, value.getQualifier().getDataType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,7 +136,7 @@ final class UDTConstant<R extends UDTRecord<R>> extends AbstractParam<R> {
|
||||
break;
|
||||
|
||||
default: {
|
||||
ctx.visit(value.getUDT());
|
||||
ctx.visit(value.getQualifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2981,7 +2981,7 @@ final class Tools {
|
||||
}
|
||||
|
||||
/**
|
||||
* Map an {@link UDTRecord} according to the configured
|
||||
* Map an {@link QualifiedRecord} according to the configured
|
||||
* {@link org.jooq.SchemaMapping}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -2990,7 +2990,7 @@ final class Tools {
|
||||
}
|
||||
|
||||
/**
|
||||
* Map an {@link UDTRecord} according to the configured
|
||||
* Map an {@link QualifiedRecord} according to the configured
|
||||
* {@link org.jooq.SchemaMapping}
|
||||
*/
|
||||
static final String getMappedUDTName(Configuration configuration, QualifiedRecord<?> record) {
|
||||
@ -5615,7 +5615,7 @@ final class Tools {
|
||||
|
||||
private static final EmbeddableRecord<?> newInstance(Class<? extends EmbeddableRecord<?>> type) {
|
||||
try {
|
||||
return type.getConstructor().newInstance();
|
||||
return type.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException("Cannot create EmbeddableRecord type", e);
|
||||
|
||||
@ -92,10 +92,10 @@ import org.jooq.EnumType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.exception.DataTypeException;
|
||||
import org.jooq.impl.IdentityConverter;
|
||||
@ -197,7 +197,7 @@ public final class Convert {
|
||||
try {
|
||||
Class<?> klass = Class.forName("com.fasterxml.jackson.databind.ObjectMapper");
|
||||
|
||||
jsonMapper = klass.getConstructor().newInstance();
|
||||
jsonMapper = klass.getDeclaredConstructor().newInstance();
|
||||
jsonReadMethod = klass.getMethod("readValue", String.class, Class.class);
|
||||
log.debug("Jackson is available");
|
||||
}
|
||||
@ -207,7 +207,7 @@ public final class Convert {
|
||||
try {
|
||||
Class<?> klass = Class.forName("com.google.gson.Gson");
|
||||
|
||||
jsonMapper = klass.getConstructor().newInstance();
|
||||
jsonMapper = klass.getDeclaredConstructor().newInstance();
|
||||
jsonReadMethod = klass.getMethod("fromJson", String.class, Class.class);
|
||||
log.debug("Gson is available");
|
||||
}
|
||||
@ -1092,9 +1092,9 @@ public final class Convert {
|
||||
else if (Struct.class.isAssignableFrom(fromClass)) {
|
||||
Struct struct = (Struct) from;
|
||||
|
||||
if (UDTRecord.class.isAssignableFrom(toClass)) {
|
||||
if (QualifiedRecord.class.isAssignableFrom(toClass)) {
|
||||
try {
|
||||
UDTRecord<?> record = ((UDTRecord<?>) toClass.newInstance());
|
||||
QualifiedRecord<?> record = ((QualifiedRecord<?>) toClass.getDeclaredConstructor().newInstance());
|
||||
record.from(struct.getAttributes());
|
||||
return (U) record;
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ public final class MiniJAXB {
|
||||
}
|
||||
else if (a != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
XmlAdapter<Object, Object> adapter = a.value().getConstructor().newInstance();
|
||||
XmlAdapter<Object, Object> adapter = a.value().getDeclaredConstructor().newInstance();
|
||||
Reflect.on(result).set(childName, adapter.unmarshal(childElement.getTextContent().trim()));
|
||||
}
|
||||
else {
|
||||
@ -438,7 +438,7 @@ public final class MiniJAXB {
|
||||
// We're assuming that XJC generated objects are all in the same package
|
||||
Package pkg = klass.getPackage();
|
||||
try {
|
||||
T defaults = klass.getConstructor().newInstance();
|
||||
T defaults = klass.getDeclaredConstructor().newInstance();
|
||||
|
||||
for (Method setter : klass.getMethods()) {
|
||||
if (setter.getName().startsWith("set")) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user