[jOOQ/jOOQ#13843] Cannot use Table as SelectField from derived table

where nesting records is supported natively
This commit is contained in:
Lukas Eder 2022-08-31 15:51:58 +02:00
parent 58a9029b20
commit 596b5d5394
7 changed files with 59 additions and 9 deletions

View File

@ -65,11 +65,17 @@ import org.jooq.Fields;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row;
import org.jooq.SelectField;
/**
* @author Lukas Eder
*/
abstract class AbstractRowAsField<R extends Record> extends AbstractField<R> {
abstract class AbstractRowAsField<R extends Record>
extends
AbstractField<R>
implements
AutoAlias<SelectField<R>>
{
AbstractRowAsField(Name name, DataType<R> type) {
super(name, type);
@ -222,6 +228,22 @@ abstract class AbstractRowAsField<R extends Record> extends AbstractField<R> {
}
}
@Override
public final SelectField<R> autoAlias(Context<?> ctx) {
// [#13843] Re-aliasing only applies if at least ROW() projection is supported natively
if (RowAsField.NO_NATIVE_SUPPORT.contains(ctx.dialect()))
return this;
// [#13843] Within MULTISET(), re-aliasing isn't required, while it leads to new edge cases
else if (forceMultisetContent(ctx, () -> getDataType().getRow().size() > 1))
return this;
// [#13843] With native support, re-alias the table as field projection
else
return new FieldAlias<>(this, getUnqualifiedName());
}
private static final Field<?> alias(Context<?> ctx, Name alias, Field<?> field) {
return ctx.declareFields() ? field.as(alias) : field;
}

View File

@ -38,6 +38,7 @@
package org.jooq.impl;
import org.jooq.Context;
import org.jooq.QueryPart;
import org.jooq.QueryPartInternal;
import org.jooq.Record;
import org.jooq.Table;
@ -48,11 +49,11 @@ import org.jooq.Table;
*
* @author Lukas Eder
*/
interface AutoAliasTable<R extends Record> extends Table<R>, QueryPartInternal {
interface AutoAlias<Q extends QueryPart> extends QueryPartInternal {
/**
* Create the aliased table expression or <code>null</code> if no auto-alias
* is required.
*/
Table<R> autoAlias(Context<?> ctx);
Q autoAlias(Context<?> ctx);
}

View File

@ -49,7 +49,13 @@ import org.jooq.QueryPart;
/**
* @author Lukas Eder
*/
final class Coerce<T> extends AbstractField<T> implements QOM.Coerce<T> {
final class Coerce<T>
extends
AbstractField<T>
implements
AutoAlias<Field<T>>,
QOM.Coerce<T>
{
final AbstractField<?> field;
@ -118,6 +124,15 @@ final class Coerce<T> extends AbstractField<T> implements QOM.Coerce<T> {
return field.generatesCast();
}
@SuppressWarnings("unchecked")
@Override
public final Field<T> autoAlias(Context<?> ctx) {
if (field instanceof AutoAlias)
return ((AutoAlias<Field<T>>) field).autoAlias(ctx).coerce(getDataType());
else
return this;
}
// -------------------------------------------------------------------------
// XXX: Query Object Model
// -------------------------------------------------------------------------

View File

@ -82,7 +82,7 @@ final class DataChangeDeltaTable<R extends Record>
extends
AbstractTable<R>
implements
AutoAliasTable<R>,
AutoAlias<Table<R>>,
QOM.DataChangeDeltaTable<R>
{

View File

@ -100,7 +100,7 @@ final class GenerateSeries
extends
AbstractTable<Record1<Integer>>
implements
AutoAliasTable<Record1<Integer>>,
AutoAlias<Table<Record1<Integer>>>,
QOM.GenerateSeries<Integer>
{

View File

@ -74,15 +74,26 @@ final class SelectFieldList<F extends SelectFieldOrAsterisk> extends QueryPartLi
return true;
}
@SuppressWarnings("unchecked")
@Override
protected void acceptElement(Context<?> ctx, F part) {
// [#4727] Various SelectFieldList references containing Table<?> cannot
// resolve the instance in time for the rendering, e.g. RETURNING
if (part instanceof AbstractTable<?> t)
ctx.visit(t.tf());
acceptElement0(ctx, (F) t.tf());
else if (part instanceof AbstractRow<?> r)
ctx.visit(r.rf());
acceptElement0(ctx, (F) r.rf());
else
acceptElement0(ctx, part);
}
@SuppressWarnings("unchecked")
private void acceptElement0(Context<?> ctx, F part) {
F alternative;
if (ctx.declareFields() && part instanceof AutoAlias && (alternative = ((AutoAlias<F>) part).autoAlias(ctx)) != null)
super.acceptElement(ctx, alternative);
else
super.acceptElement(ctx, part);
}

View File

@ -82,11 +82,12 @@ final class TableList extends QueryPartList<Table<?>> {
return true;
}
@SuppressWarnings("unchecked")
@Override
protected void acceptElement(Context<?> ctx, Table<?> part) {
Table<?> alternative;
if (ctx.declareTables() && part instanceof AutoAliasTable && (alternative = ((AutoAliasTable<?>) part).autoAlias(ctx)) != null)
if (ctx.declareTables() && part instanceof AutoAlias && (alternative = ((AutoAlias<Table<?>>) part).autoAlias(ctx)) != null)
super.acceptElement(ctx, alternative);
else
super.acceptElement(ctx, part);