From 596b5d53941db36cbe45f8db3617538a56033682 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 31 Aug 2022 15:51:58 +0200 Subject: [PATCH] [jOOQ/jOOQ#13843] Cannot use Table as SelectField from derived table where nesting records is supported natively --- .../org/jooq/impl/AbstractRowAsField.java | 24 ++++++++++++++++++- .../{AutoAliasTable.java => AutoAlias.java} | 5 ++-- jOOQ/src/main/java/org/jooq/impl/Coerce.java | 17 ++++++++++++- .../org/jooq/impl/DataChangeDeltaTable.java | 2 +- .../java/org/jooq/impl/GenerateSeries.java | 2 +- .../java/org/jooq/impl/SelectFieldList.java | 15 ++++++++++-- .../main/java/org/jooq/impl/TableList.java | 3 ++- 7 files changed, 59 insertions(+), 9 deletions(-) rename jOOQ/src/main/java/org/jooq/impl/{AutoAliasTable.java => AutoAlias.java} (91%) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRowAsField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRowAsField.java index aff84faa35..d83bca2289 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRowAsField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRowAsField.java @@ -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 extends AbstractField { +abstract class AbstractRowAsField +extends + AbstractField +implements + AutoAlias> +{ AbstractRowAsField(Name name, DataType type) { super(name, type); @@ -222,6 +228,22 @@ abstract class AbstractRowAsField extends AbstractField { } } + @Override + public final SelectField 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; } diff --git a/jOOQ/src/main/java/org/jooq/impl/AutoAliasTable.java b/jOOQ/src/main/java/org/jooq/impl/AutoAlias.java similarity index 91% rename from jOOQ/src/main/java/org/jooq/impl/AutoAliasTable.java rename to jOOQ/src/main/java/org/jooq/impl/AutoAlias.java index ba539c651f..5195fadfc6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AutoAliasTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AutoAlias.java @@ -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 extends Table, QueryPartInternal { +interface AutoAlias extends QueryPartInternal { /** * Create the aliased table expression or null if no auto-alias * is required. */ - Table autoAlias(Context ctx); + Q autoAlias(Context ctx); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Coerce.java b/jOOQ/src/main/java/org/jooq/impl/Coerce.java index e822f8f96e..99722bd53d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Coerce.java +++ b/jOOQ/src/main/java/org/jooq/impl/Coerce.java @@ -49,7 +49,13 @@ import org.jooq.QueryPart; /** * @author Lukas Eder */ -final class Coerce extends AbstractField implements QOM.Coerce { +final class Coerce +extends + AbstractField +implements + AutoAlias>, + QOM.Coerce +{ final AbstractField field; @@ -118,6 +124,15 @@ final class Coerce extends AbstractField implements QOM.Coerce { return field.generatesCast(); } + @SuppressWarnings("unchecked") + @Override + public final Field autoAlias(Context ctx) { + if (field instanceof AutoAlias) + return ((AutoAlias>) field).autoAlias(ctx).coerce(getDataType()); + else + return this; + } + // ------------------------------------------------------------------------- // XXX: Query Object Model // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java b/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java index bfbd36fb3d..ab7fbb00d8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java @@ -82,7 +82,7 @@ final class DataChangeDeltaTable extends AbstractTable implements - AutoAliasTable, + AutoAlias>, QOM.DataChangeDeltaTable { diff --git a/jOOQ/src/main/java/org/jooq/impl/GenerateSeries.java b/jOOQ/src/main/java/org/jooq/impl/GenerateSeries.java index c06f1e7099..e291c3b1a9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/GenerateSeries.java +++ b/jOOQ/src/main/java/org/jooq/impl/GenerateSeries.java @@ -100,7 +100,7 @@ final class GenerateSeries extends AbstractTable> implements - AutoAliasTable>, + AutoAlias>>, QOM.GenerateSeries { diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectFieldList.java b/jOOQ/src/main/java/org/jooq/impl/SelectFieldList.java index 72b29685bc..31f81cd861 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectFieldList.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectFieldList.java @@ -74,15 +74,26 @@ final class SelectFieldList 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) part).autoAlias(ctx)) != null) + super.acceptElement(ctx, alternative); else super.acceptElement(ctx, part); } diff --git a/jOOQ/src/main/java/org/jooq/impl/TableList.java b/jOOQ/src/main/java/org/jooq/impl/TableList.java index cfb5720a93..b04fc047b6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableList.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableList.java @@ -82,11 +82,12 @@ final class TableList extends QueryPartList> { 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>) part).autoAlias(ctx)) != null) super.acceptElement(ctx, alternative); else super.acceptElement(ctx, part);