[jOOQ/jOOQ#8353] Fix known limitations of embeddable types
- Embeddables in scalar subqueries - [jOOQ/jOOQ#10524] Better use of DataType::isEmbeddable
This commit is contained in:
parent
fdc05e3349
commit
5c97467580
@ -44,7 +44,6 @@ import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.converterOrFail;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
import static org.jooq.impl.Tools.resetChangedOnNotNull;
|
||||
import static org.jooq.impl.Tools.settings;
|
||||
import static org.jooq.impl.Tools.ThreadGuard.Guard.RECORD_TOSTRING;
|
||||
@ -330,7 +329,7 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
|
||||
@Override
|
||||
public final <T> void set(Field<T> field, T value) {
|
||||
if (isEmbeddable(field)) {
|
||||
if (field.getDataType().isEmbeddable()) {
|
||||
Field<?>[] f = embeddedFields(field);
|
||||
Object[] v = value instanceof EmbeddableRecord
|
||||
? ((EmbeddableRecord) value).intoArray()
|
||||
|
||||
@ -72,7 +72,6 @@ import static org.jooq.impl.Keywords.K_BETWEEN;
|
||||
import static org.jooq.impl.Keywords.K_NOT;
|
||||
import static org.jooq.impl.Keywords.K_SYMMETRIC;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -138,7 +137,9 @@ final class BetweenCondition<T> extends AbstractCondition implements BetweenAndS
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
if (isEmbeddable(field) && isEmbeddable(minValue) && isEmbeddable(maxValue)) {
|
||||
if (field.getDataType().isEmbeddable()
|
||||
&& minValue.getDataType().isEmbeddable()
|
||||
&& maxValue.getDataType().isEmbeddable()) {
|
||||
RowN f = row(embeddedFields(field));
|
||||
RowN min = row(embeddedFields(minValue));
|
||||
RowN max = row(embeddedFields(maxValue));
|
||||
|
||||
@ -80,7 +80,6 @@ import static org.jooq.impl.Keywords.K_ESCAPE;
|
||||
import static org.jooq.impl.Keywords.K_VARCHAR;
|
||||
import static org.jooq.impl.Tools.castIfNeeded;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -122,9 +121,9 @@ final class CompareCondition extends AbstractCondition implements LikeEscapeStep
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
boolean field1Embeddable = isEmbeddable(field1);
|
||||
boolean field1Embeddable = field1.getDataType().isEmbeddable();
|
||||
|
||||
if (field1Embeddable && isEmbeddable(field2))
|
||||
if (field1Embeddable && field2.getDataType().isEmbeddable())
|
||||
ctx.visit(row(embeddedFields(field1)).compare(comparator, embeddedFields(field2)));
|
||||
else if (field1Embeddable && field2 instanceof ScalarSubquery)
|
||||
ctx.visit(row(embeddedFields(field1)).compare(comparator, ((ScalarSubquery<?>) field2).query));
|
||||
|
||||
@ -39,6 +39,7 @@ package org.jooq.impl;
|
||||
|
||||
// ...
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.embeddedRecordType;
|
||||
import static org.jooq.impl.Tools.recordFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
@ -1698,9 +1699,9 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
|
||||
// TODO: [#4695] Calculate the correct Record[B] type
|
||||
recordType = RecordImplN.class;
|
||||
}
|
||||
else if (field instanceof EmbeddableTableField) {
|
||||
else if (field.getDataType().isEmbeddable()) {
|
||||
nested = embeddedFields(field);
|
||||
recordType = (Class<AbstractRecord>) ((EmbeddableTableField<?, ?>) field).recordType;
|
||||
recordType = embeddedRecordType(field);
|
||||
}
|
||||
|
||||
if (nested != null) {
|
||||
|
||||
@ -41,6 +41,7 @@ import static org.jooq.impl.QueryPartListView.wrap;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.SQLDialect;
|
||||
@ -50,18 +51,20 @@ import org.jooq.TableField;
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class EmbeddableTableField<R extends Record, T extends Record> extends AbstractField<T> implements TableField<R, T> {
|
||||
final class EmbeddableTableField<R extends Record, E extends EmbeddableRecord<E>>
|
||||
extends AbstractField<E>
|
||||
implements TableField<R, E> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -7105430856294526440L;
|
||||
final Class<T> recordType;
|
||||
final Class<E> recordType;
|
||||
final boolean replacesFields;
|
||||
final Table<R> table;
|
||||
final TableField<R, ?>[] fields;
|
||||
|
||||
EmbeddableTableField(Name name, Class<T> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>[] fields) {
|
||||
EmbeddableTableField(Name name, Class<E> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>[] fields) {
|
||||
super(name, new DefaultDataType<>(SQLDialect.DEFAULT, recordType, name.last()));
|
||||
|
||||
this.recordType = recordType;
|
||||
|
||||
@ -49,7 +49,6 @@ import static org.jooq.impl.Keywords.K_VALUES;
|
||||
import static org.jooq.impl.Tools.collect;
|
||||
import static org.jooq.impl.Tools.flatten;
|
||||
import static org.jooq.impl.Tools.flattenCollection;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
import static org.jooq.impl.Tools.lazy;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_EMULATE_BULK_INSERT_RETURNING;
|
||||
|
||||
|
||||
@ -79,7 +79,6 @@ import static org.jooq.impl.DSL.trueCondition;
|
||||
import static org.jooq.impl.Keywords.K_AND;
|
||||
import static org.jooq.impl.Keywords.K_OR;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
import static org.jooq.tools.StringUtils.defaultIfNull;
|
||||
|
||||
import java.util.AbstractList;
|
||||
@ -122,7 +121,7 @@ final class InCondition<T> extends AbstractCondition {
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (isEmbeddable(field))
|
||||
if (field.getDataType().isEmbeddable())
|
||||
if (comparator == IN)
|
||||
ctx.visit(row(embeddedFields(field)).in(rows()));
|
||||
else
|
||||
|
||||
@ -79,7 +79,7 @@ public final class Internal {
|
||||
*/
|
||||
@SafeVarargs
|
||||
@NotNull
|
||||
public static final <R extends Record, T extends Record> TableField<R, T> createEmbeddable(Name name, Class<T> recordType, Table<R> table, TableField<R, ?>... fields) {
|
||||
public static final <R extends Record, E extends EmbeddableRecord<E>> TableField<R, E> createEmbeddable(Name name, Class<E> recordType, Table<R> table, TableField<R, ?>... fields) {
|
||||
return createEmbeddable(name, recordType, false, table, fields);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ public final class Internal {
|
||||
*/
|
||||
@SafeVarargs
|
||||
@NotNull
|
||||
public static final <R extends Record, T extends Record> TableField<R, T> createEmbeddable(Name name, Class<T> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>... fields) {
|
||||
public static final <R extends Record, E extends EmbeddableRecord<E>> TableField<R, E> createEmbeddable(Name name, Class<E> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>... fields) {
|
||||
return new EmbeddableTableField<>(name, recordType, replacesFields, table, fields);
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,6 @@ import static org.jooq.impl.DSL.notExists;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -112,7 +111,7 @@ final class IsDistinctFrom<T> extends AbstractCondition {
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (isEmbeddable(lhs) && isEmbeddable(rhs))
|
||||
if (lhs.getDataType().isEmbeddable() && rhs.getDataType().isEmbeddable())
|
||||
ctx.visit(row(embeddedFields(lhs)).compare(comparator, row(embeddedFields(rhs))));
|
||||
|
||||
|
||||
|
||||
@ -45,7 +45,6 @@ import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.Keywords.K_IS_NOT_NULL;
|
||||
import static org.jooq.impl.Keywords.K_IS_NULL;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Context;
|
||||
@ -75,7 +74,7 @@ final class IsNull extends AbstractCondition {
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (isEmbeddable(field))
|
||||
if (field.getDataType().isEmbeddable())
|
||||
if (isNull)
|
||||
ctx.visit(row(embeddedFields(field)).isNull());
|
||||
else
|
||||
|
||||
@ -72,7 +72,6 @@ import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.SQLDataType.VARCHAR;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
import static org.jooq.tools.Convert.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -123,7 +122,7 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (isEmbeddable(field))
|
||||
if (field.getDataType().isEmbeddable())
|
||||
ctx.visit(row(embeddedFields(field)).compare(comparator, query));
|
||||
else
|
||||
accept0(ctx);
|
||||
|
||||
@ -5335,9 +5335,15 @@ final class Tools {
|
||||
return array == null || array.length == 0;
|
||||
}
|
||||
|
||||
static final boolean isEmbeddable(Field<?> field) {
|
||||
@SuppressWarnings("unchecked")
|
||||
static final Class<? extends AbstractRecord> embeddedRecordType(Field<?> field) {
|
||||
return field instanceof EmbeddableTableField
|
||||
|| field instanceof Val && EmbeddableRecord.class.isAssignableFrom(field.getType());
|
||||
? (Class<AbstractRecord>) ((EmbeddableTableField<?, ?>) field).recordType
|
||||
: field instanceof Val && ((Val<?>) field).value instanceof EmbeddableRecord
|
||||
? ((AbstractRecord) ((Val<?>) field).value).getClass()
|
||||
: EmbeddableRecord.class.isAssignableFrom(field.getType())
|
||||
? ((Field<AbstractRecord>) field).getType()
|
||||
: null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -5346,12 +5352,10 @@ final class Tools {
|
||||
? ((EmbeddableTableField<?, ?>) field).fields
|
||||
: field instanceof Val && ((Val<?>) field).value instanceof EmbeddableRecord
|
||||
? ((EmbeddableRecord<?>) ((Val<?>) field).value).valuesRow().fields()
|
||||
|
||||
// It's an embeddable type, but it is null
|
||||
: field instanceof Val && EmbeddableRecord.class.isAssignableFrom(field.getType())
|
||||
? newInstance((Class<? extends EmbeddableRecord<?>>) field.getType()).valuesRow().fields()
|
||||
: field instanceof ScalarSubquery
|
||||
? embeddedFields((ScalarSubquery<?>) field)
|
||||
: EmbeddableRecord.class.isAssignableFrom(field.getType())
|
||||
? newInstance(((Field<EmbeddableRecord<?>>) field).getType()).valuesRow().fields()
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user