[jOOQ/jOOQ#16655] MULTISET nested projection's ContextConverters don't receive correct ConverterContext
This commit is contained in:
parent
948901a2b4
commit
e7882b314e
@ -67,6 +67,7 @@ import static org.jooq.SQLDialect.TRINO;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.YUGABYTEDB;
|
||||
import static org.jooq.impl.Internal.arrayType;
|
||||
import static org.jooq.impl.Internal.converterContext;
|
||||
import static org.jooq.impl.QOM.GenerationOption.STORED;
|
||||
import static org.jooq.impl.QOM.GenerationOption.VIRTUAL;
|
||||
import static org.jooq.impl.SQLDataType.BLOB;
|
||||
@ -111,6 +112,7 @@ import org.jooq.Configuration;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.ContextConverter;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Domain;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
@ -831,7 +833,11 @@ implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public /* non-final */ T convert(Object object) {
|
||||
public final T convert(Object object) {
|
||||
return convert(object, converterContext());
|
||||
}
|
||||
|
||||
/* non-final */ T convert(Object object, ConverterContext cc) {
|
||||
|
||||
// [#1441] Avoid unneeded type conversions to improve performance
|
||||
if (object == null)
|
||||
|
||||
@ -67,6 +67,7 @@ import org.jooq.Attachable;
|
||||
import org.jooq.CSVFormat;
|
||||
import org.jooq.ChartFormat;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
@ -718,10 +719,12 @@ implements
|
||||
|
||||
class TransferRecordState<R extends Record> implements ThrowingFunction<R, R, MappingException> {
|
||||
|
||||
private final Field<?>[] targetFields;
|
||||
final ConverterContext converterContext;
|
||||
final Field<?>[] targetFields;
|
||||
|
||||
TransferRecordState(Field<?>[] targetFields) {
|
||||
this.targetFields = targetFields;
|
||||
this.converterContext = converterContext(AbstractRecord.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -755,7 +758,7 @@ implements
|
||||
Field<?> sourceField = field(targetField);
|
||||
|
||||
if (sourceField != null)
|
||||
Tools.setValue(target, targetField, source, sourceField);
|
||||
Tools.setValue(target, targetField, source, sourceField, converterContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,11 +913,13 @@ implements
|
||||
* public for broader use...?
|
||||
*/
|
||||
protected final void from(Record source) {
|
||||
ConverterContext cc = Tools.converterContext(this);
|
||||
|
||||
for (Field<?> field : fields.fields.fields) {
|
||||
Field<?> sourceField = source.field(field);
|
||||
|
||||
if (sourceField != null && source.changed(sourceField))
|
||||
Tools.setValue(this, field, source, sourceField);
|
||||
Tools.setValue(this, field, source, sourceField, cc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ import org.jooq.CharacterSet;
|
||||
import org.jooq.Collation;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.Converters;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
@ -300,7 +301,7 @@ final class ConvertedDataType<T, U> extends AbstractDataTypeX<U> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final U convert(Object object) {
|
||||
final U convert(Object object, ConverterContext cc) {
|
||||
if (getConverter().toType().isInstance(object))
|
||||
return (U) object;
|
||||
|
||||
@ -316,7 +317,7 @@ final class ConvertedDataType<T, U> extends AbstractDataTypeX<U> {
|
||||
|
||||
// [#3200] Try to convert arbitrary objects to T
|
||||
else
|
||||
return ((ContextConverter<T, U>) getConverter()).from(delegate.convert(object), converterContext());
|
||||
return ((ContextConverter<T, U>) getConverter()).from(delegate.convert(object, cc), cc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Tools.converterContext;
|
||||
import static org.jooq.impl.Tools.getAnnotatedGetter;
|
||||
import static org.jooq.impl.Tools.getAnnotatedMembers;
|
||||
import static org.jooq.impl.Tools.getMatchingGetter;
|
||||
@ -51,6 +52,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordType;
|
||||
@ -80,6 +82,7 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
private final Class<? extends AbstractRecord> recordType;
|
||||
private final Field<?>[] fields;
|
||||
private final Configuration configuration;
|
||||
private final ConverterContext converterContext;
|
||||
private RecordUnmapper<E, R> delegate;
|
||||
|
||||
public DefaultRecordUnmapper(Class<? extends E> type, RecordType<R> rowType, Configuration configuration) {
|
||||
@ -89,6 +92,7 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
this.recordType = Tools.recordType(rowType.size());
|
||||
this.fields = rowType.fields();
|
||||
this.configuration = configuration;
|
||||
this.converterContext = converterContext(configuration);
|
||||
|
||||
init();
|
||||
}
|
||||
@ -115,31 +119,31 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
return Tools.newRecord(false, recordType, row, configuration).operate(null);
|
||||
}
|
||||
|
||||
private static final void setValue(Record record, Object source, java.lang.reflect.Field member, Field<?> field)
|
||||
private static final void setValue(Record record, Object source, java.lang.reflect.Field member, Field<?> field, ConverterContext converterContext)
|
||||
throws IllegalAccessException {
|
||||
|
||||
Class<?> mType = member.getType();
|
||||
|
||||
if (mType.isPrimitive()) {
|
||||
if (mType == byte.class)
|
||||
Tools.setValue(record, field, member.getByte(source));
|
||||
Tools.setValue(record, field, member.getByte(source), converterContext);
|
||||
else if (mType == short.class)
|
||||
Tools.setValue(record, field, member.getShort(source));
|
||||
Tools.setValue(record, field, member.getShort(source), converterContext);
|
||||
else if (mType == int.class)
|
||||
Tools.setValue(record, field, member.getInt(source));
|
||||
Tools.setValue(record, field, member.getInt(source), converterContext);
|
||||
else if (mType == long.class)
|
||||
Tools.setValue(record, field, member.getLong(source));
|
||||
Tools.setValue(record, field, member.getLong(source), converterContext);
|
||||
else if (mType == float.class)
|
||||
Tools.setValue(record, field, member.getFloat(source));
|
||||
Tools.setValue(record, field, member.getFloat(source), converterContext);
|
||||
else if (mType == double.class)
|
||||
Tools.setValue(record, field, member.getDouble(source));
|
||||
Tools.setValue(record, field, member.getDouble(source), converterContext);
|
||||
else if (mType == boolean.class)
|
||||
Tools.setValue(record, field, member.getBoolean(source));
|
||||
Tools.setValue(record, field, member.getBoolean(source), converterContext);
|
||||
else if (mType == char.class)
|
||||
Tools.setValue(record, field, member.getChar(source));
|
||||
Tools.setValue(record, field, member.getChar(source), converterContext);
|
||||
}
|
||||
else
|
||||
Tools.setValue(record, field, member.get(source));
|
||||
Tools.setValue(record, field, member.get(source), converterContext);
|
||||
}
|
||||
|
||||
private final class ArrayUnmapper implements RecordUnmapper<E, R> {
|
||||
@ -152,7 +156,7 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
AbstractRecord record = (AbstractRecord) newRecord();
|
||||
|
||||
for (int i = 0; i < size && i < array.length; i++)
|
||||
Tools.setValue(record, rowType.field(i), i, array[i]);
|
||||
Tools.setValue(record, rowType.field(i), i, array[i], converterContext);
|
||||
|
||||
return (R) record;
|
||||
}
|
||||
@ -172,7 +176,7 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
AbstractRecord record = (AbstractRecord) newRecord();
|
||||
|
||||
for (int i = 0; i < size && it.hasNext(); i++)
|
||||
Tools.setValue(record, rowType.field(i), i, it.next());
|
||||
Tools.setValue(record, rowType.field(i), i, it.next(), converterContext);
|
||||
|
||||
return (R) record;
|
||||
}
|
||||
@ -217,7 +221,7 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
|
||||
// Set only those values contained in the map
|
||||
if (map.containsKey(name))
|
||||
Tools.setValue(record, fields[i], map.get(name));
|
||||
Tools.setValue(record, fields[i], map.get(name), converterContext);
|
||||
}
|
||||
|
||||
return (R) record;
|
||||
@ -255,9 +259,9 @@ public class DefaultRecordUnmapper<E, R extends Record> implements RecordUnmappe
|
||||
|
||||
// Use only the first applicable method or member
|
||||
if (method != null)
|
||||
Tools.setValue(record, field, method.invoke(source));
|
||||
Tools.setValue(record, field, method.invoke(source), converterContext);
|
||||
else if (members.size() > 0)
|
||||
setValue(record, source, members.get(0), field);
|
||||
setValue(record, source, members.get(0), field, converterContext);
|
||||
}
|
||||
|
||||
return (R) record;
|
||||
|
||||
@ -44,6 +44,7 @@ import org.jooq.CharacterSet;
|
||||
import org.jooq.Collation;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Generator;
|
||||
@ -136,13 +137,13 @@ final class LegacyConvertedDataType<T, U> extends DefaultDataType<U> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public U convert(Object object) {
|
||||
final U convert(Object object, ConverterContext cc) {
|
||||
if (getConverter().toType().isInstance(object))
|
||||
return (U) object;
|
||||
|
||||
// [#3200] Try to convert arbitrary objects to T
|
||||
else
|
||||
return ((ContextConverter<T, U>) getConverter()).from(delegate.convert(object), converterContext());
|
||||
return ((ContextConverter<T, U>) getConverter()).from(delegate.convert(object, cc), cc);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
||||
@ -45,13 +45,13 @@ import static org.jooq.impl.Tools.newRecord;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Struct;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jooq.CharacterSet;
|
||||
import org.jooq.Collation;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Generator;
|
||||
import org.jooq.Nullability;
|
||||
@ -155,9 +155,9 @@ final class MultisetDataType<R extends Record> extends DefaultDataType<Result<R>
|
||||
return recordType;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public Result<R> convert(Object object) {
|
||||
final Result<R> convert(Object object, ConverterContext cc) {
|
||||
|
||||
// [#12269] [#13403] Don't re-copy perfectly fine results.
|
||||
if (object instanceof Result && ((Result<?>) object).fieldsRow().equals(row))
|
||||
@ -187,11 +187,11 @@ final class MultisetDataType<R extends Record> extends DefaultDataType<Result<R>
|
||||
return result;
|
||||
}
|
||||
else if (object instanceof Object[] a) {
|
||||
return convert((Object) asList(a));
|
||||
return convert(asList(a), cc);
|
||||
}
|
||||
else if (object instanceof Array a) {
|
||||
try {
|
||||
return convert((Object) asList((Object[]) a.getArray()));
|
||||
return convert(asList((Object[]) a.getArray()), cc);
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new DataAccessException("Error while accessing array", e);
|
||||
@ -200,6 +200,6 @@ final class MultisetDataType<R extends Record> extends DefaultDataType<Result<R>
|
||||
else if (object == null)
|
||||
return new ResultImpl<>(CONFIG.get(), row);
|
||||
else
|
||||
return super.convert(object);
|
||||
return super.convert(object, cc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.jooq.CharacterSet;
|
||||
import org.jooq.Collation;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Generator;
|
||||
import org.jooq.Nullability;
|
||||
@ -158,7 +159,7 @@ final class RecordDataType<R extends Record> extends DefaultDataType<R> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public R convert(Object object) {
|
||||
final R convert(Object object, ConverterContext cc) {
|
||||
|
||||
// [#12269] [#13403] Don't re-copy perfectly fine results.
|
||||
if (object instanceof Record && ((Record) object).fieldsRow().equals(row))
|
||||
@ -188,6 +189,6 @@ final class RecordDataType<R extends Record> extends DefaultDataType<R> {
|
||||
});
|
||||
}
|
||||
else
|
||||
return super.convert(object);
|
||||
return super.convert(object, cc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3711,29 +3711,22 @@ final class Tools {
|
||||
/**
|
||||
* Type-safely copy a value from one record to another
|
||||
*/
|
||||
static final <T> void setValue(Record target, Field<T> targetField, Record source, Field<?> sourceField) {
|
||||
setValue(target, targetField, source.get(sourceField));
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safely copy a value from one record to another
|
||||
*/
|
||||
static final <T> void setValue(AbstractRecord target, Field<T> targetField, int targetIndex, Record source, int sourceIndex) {
|
||||
setValue(target, targetField, targetIndex, source.get(sourceIndex));
|
||||
static final <T> void setValue(Record target, Field<T> targetField, Record source, Field<?> sourceField, ConverterContext cc) {
|
||||
setValue(target, targetField, source.get(sourceField), cc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safely set a value to a record
|
||||
*/
|
||||
static final <T> void setValue(Record target, Field<T> targetField, Object value) {
|
||||
target.set(targetField, targetField.getDataType().convert(value));
|
||||
static final <T> void setValue(Record target, Field<T> targetField, Object value, ConverterContext cc) {
|
||||
target.set(targetField, ((AbstractDataType<T>) targetField.getDataType()).convert(value, cc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safely set a value to a record
|
||||
*/
|
||||
static final <T> void setValue(AbstractRecord target, Field<T> targetField, int targetIndex, Object value) {
|
||||
target.set(targetField, targetIndex, targetField.getDataType().convert(value));
|
||||
static final <T> void setValue(AbstractRecord target, Field<T> targetField, int targetIndex, Object value, ConverterContext cc) {
|
||||
target.set(targetField, targetIndex, ((AbstractDataType<T>) targetField.getDataType()).convert(value, cc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user