[jOOQ/jOOQ#4727] Support the feature also in CRDB

This commit is contained in:
Lukas Eder 2022-03-07 14:49:41 +01:00
parent 4a06ec9a00
commit 86049a8ea5
7 changed files with 29 additions and 12 deletions

View File

@ -80,6 +80,8 @@ abstract class AbstractRowAsField<R extends Record> extends AbstractField<R> {
return (AbstractRow<R>) row0(map(fields0().fields(), x -> x.as(getUnqualifiedName().unquotedName() + configuration.settings().getNamePathSeparator() + x.getName()), Field[]::new));
}
abstract boolean noNativeSupport(Context<?> ctx);
@Override
final int projectionSize() {
int result = 0;
@ -100,13 +102,17 @@ abstract class AbstractRowAsField<R extends Record> extends AbstractField<R> {
// [#12021] If a RowField is nested somewhere in MULTISET, we must apply
// the MULTISET emulation as well, here
if (forceMultisetContent(ctx, () -> getDataType().getRow().size() > 1))
if (forceMultisetContent(ctx, () -> noNativeSupport(ctx), () -> getDataType().getRow().size() > 1))
acceptMultisetContent(ctx, getDataType().getRow(), this, this::acceptDefault);
else
acceptDefault(ctx);
}
static final boolean forceMultisetContent(Context<?> ctx, BooleanSupplier degreeCheck) {
static final boolean forceMultisetContent(
Context<?> ctx,
BooleanSupplier noNativeSupportCheck,
BooleanSupplier degreeCheck
) {
return
// All types of row expressions must be emulated using MULTISET
@ -118,7 +124,7 @@ abstract class AbstractRowAsField<R extends Record> extends AbstractField<R> {
// subqueries, where row subqueries are usually supported, e.g.
// (a, b) IN (SELECT x, y)
|| ctx.subquery()
&& RowAsField.NO_NATIVE_SUPPORT.contains(ctx.dialect())
&& noNativeSupportCheck.getAsBoolean()
&& !ctx.predicandSubquery()
&& !ctx.derivedTableSubquery()
&& !ctx.setOperationSubquery()

View File

@ -1547,11 +1547,11 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> {
// RowField may have a Row[N].mapping(...) applied
Field<?> f = uncoerce(field);
if (f instanceof RowAsField && NO_NATIVE_SUPPORT.contains(ctx.dialect())) {
if (f instanceof RowAsField && RowAsField.NO_NATIVE_SUPPORT.contains(ctx.dialect())) {
nested = ((RowAsField<?, ?>) f).emulatedFields(configuration);
recordType = Tools.recordType(nested.size());
}
else if (f instanceof TableAsField && NO_NATIVE_SUPPORT.contains(ctx.dialect())) {
else if (f instanceof TableAsField && TableAsField.NO_NATIVE_SUPPORT.contains(ctx.dialect())) {
nested = ((TableAsField<?>) f).emulatedFields(configuration);
recordType = (Class<? extends AbstractRecord>) ((TableAsField<?>) f).table.getRecordType();
}

View File

@ -40,6 +40,7 @@ package org.jooq.impl;
import static org.jooq.impl.AbstractRowAsField.acceptMultisetContent;
import static org.jooq.impl.AbstractRowAsField.forceMultisetContent;
import static org.jooq.impl.QueryPartListView.wrap;
import static org.jooq.impl.RowAsField.NO_NATIVE_SUPPORT;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
import org.jooq.Context;
@ -96,7 +97,7 @@ implements
// TODO [#12021] [#12706] ROW must consistently follow MULTISET emulation
// [#12237] If a RowField is nested somewhere in MULTISET, we must apply
// the MULTISET emulation as well, here
if (forceMultisetContent(ctx, () -> getDataType().getRow().size() > 1))
if (forceMultisetContent(ctx, () -> NO_NATIVE_SUPPORT.contains(ctx.dialect()), () -> getDataType().getRow().size() > 1))
acceptMultisetContent(ctx, getDataType().getRow(), this, this::acceptDefault);
else
acceptDefault(ctx);

View File

@ -45,10 +45,8 @@ import static org.jooq.impl.AbstractRowAsField.forceMultisetContent;
import static org.jooq.impl.DSL.NULL;
import static org.jooq.impl.DSL.case_;
import static org.jooq.impl.DSL.coalesce;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.iif;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.inlined;
import static org.jooq.impl.DSL.nvl;
@ -62,6 +60,7 @@ import static org.jooq.impl.Names.N_JSON_EXTRACT;
import static org.jooq.impl.Names.N_JSON_MERGE;
import static org.jooq.impl.Names.N_JSON_MERGE_PRESERVE;
import static org.jooq.impl.Names.N_JSON_QUERY;
import static org.jooq.impl.RowAsField.NO_NATIVE_SUPPORT;
import static org.jooq.impl.SQLDataType.BIT;
import static org.jooq.impl.SQLDataType.BOOLEAN;
import static org.jooq.impl.SQLDataType.VARCHAR;
@ -305,8 +304,8 @@ final class JSONEntryImpl<T> extends AbstractQueryPart implements JSONEntry<T>,
: type;
return t.isJSON()
|| t.isEmbeddable() && forceMultisetContent(ctx, () -> t.getRow().size() > 1) && emulateMultisetWithJSON(ctx)
|| t.isRecord() && forceMultisetContent(ctx, () -> t.getRow().size() > 1) && emulateMultisetWithJSON(ctx)
|| t.isEmbeddable() && forceMultisetContent(ctx, () -> NO_NATIVE_SUPPORT.contains(ctx.dialect()), () -> t.getRow().size() > 1) && emulateMultisetWithJSON(ctx)
|| t.isRecord() && forceMultisetContent(ctx, () -> NO_NATIVE_SUPPORT.contains(ctx.dialect()), () -> t.getRow().size() > 1) && emulateMultisetWithJSON(ctx)
|| t.isMultiset() && emulateMultisetWithJSON(ctx);
}

View File

@ -66,7 +66,6 @@ import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
import static org.jooq.impl.Keywords.K_ROW;
import static org.jooq.impl.Names.N_ROW;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
import java.util.Set;
@ -100,6 +99,11 @@ final class RowAsField<ROW extends Row, REC extends Record> extends AbstractRowA
this.row = row;
}
@Override
final boolean noNativeSupport(Context<?> ctx) {
return NO_NATIVE_SUPPORT.contains(ctx.dialect());
}
@Override
final ROW fields0() {
return row;

View File

@ -41,6 +41,7 @@ package org.jooq.impl;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@ -107,6 +108,11 @@ implements
this.table = table;
}
@Override
final boolean noNativeSupport(Context<?> ctx) {
return NO_NATIVE_SUPPORT.contains(ctx.dialect());
}
@Override
final Table<R> fields0() {
return table;

View File

@ -46,6 +46,7 @@ import static org.jooq.impl.AbstractRowAsField.acceptMultisetContent;
import static org.jooq.impl.AbstractRowAsField.forceMultisetContent;
import static org.jooq.impl.DSL.sql;
import static org.jooq.impl.QueryPartListView.wrap;
import static org.jooq.impl.RowAsField.NO_NATIVE_SUPPORT;
import static org.jooq.impl.SQLDataType.OTHER;
import static org.jooq.impl.SQLDataType.VARCHAR;
import static org.jooq.impl.Tools.embeddedFields;
@ -163,7 +164,7 @@ final class Val<T> extends AbstractParam<T> implements QOM.Val<T>, UEmpty {
// TODO [#12021] [#12706] ROW must consistently follow MULTISET emulation
// [#12237] If a RowField is nested somewhere in MULTISET, we must apply
// the MULTISET emulation as well, here
if (forceMultisetContent(ctx, () -> embeddedFields(this).length > 1))
if (forceMultisetContent(ctx, () -> NO_NATIVE_SUPPORT.contains(ctx.dialect()), () -> embeddedFields(this).length > 1))
acceptMultisetContent(ctx, row0(embeddedFields(this)), this, this::acceptDefaultEmbeddable);
else
acceptDefaultEmbeddable(ctx);