[jOOQ/jOOQ#14560] Refactor QuantifiedSelectImpl into separate subtypes

This commit is contained in:
Lukas Eder 2023-01-27 11:05:55 +01:00
parent 361fd95cc9
commit eb6ce5087e
10 changed files with 352 additions and 221 deletions

View File

@ -120,8 +120,8 @@ final class Array<T> extends AbstractField<T[]> implements QOM.Array<T> {
// -------------------------------------------------------------------------
@Override
public final UnmodifiableList<? extends Field<?>> $elements() {
return QOM.unmodifiable(fields.fields);
public final UnmodifiableList<? extends Field<T>> $elements() {
return (UnmodifiableList<? extends Field<T>>) QOM.unmodifiable(fields.fields);
}

View File

@ -37,7 +37,6 @@
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.Keywords.K_TABLE;
import static org.jooq.impl.Keywords.K_UNNEST;
import static org.jooq.impl.Names.N_ARRAY_TABLE;

View File

@ -432,6 +432,7 @@ import org.jooq.conf.RenderQuotedNames;
import org.jooq.conf.Settings;
import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.QOM.DocumentOrContent;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.QOM.ResultOption;
import org.jooq.tools.StringUtils;
import org.jooq.tools.jdbc.JDBCUtils;
@ -10917,7 +10918,7 @@ public class DSL {
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, YUGABYTEDB })
public static <T> QuantifiedSelect<Record1<T>> all(T... array) {
return array instanceof Field[] ? all((Field<T>[]) array) : new QuantifiedSelectImpl<>(Quantifier.ALL, val(array));
return array instanceof Field[] ? all((Field<T>[]) array) : new QuantifiedArray<>(Quantifier.ALL, val(array));
}
/**
@ -10938,7 +10939,7 @@ public class DSL {
@NotNull
@Support({ H2, HSQLDB, POSTGRES, YUGABYTEDB })
public static <T> QuantifiedSelect<Record1<T>> all(Field<T[]> array) {
return new QuantifiedSelectImpl<>(Quantifier.ALL, array);
return new QuantifiedArray<>(Quantifier.ALL, array);
}
/**
@ -10960,7 +10961,7 @@ public class DSL {
@Support
@SafeVarargs
public static <T> QuantifiedSelect<Record1<T>> all(Field<T>... fields) {
return new QuantifiedSelectImpl<>(Quantifier.ALL, fields);
return new QuantifiedArray<>(Quantifier.ALL, new Array<>(asList(fields)));
}
/**
@ -10999,7 +11000,7 @@ public class DSL {
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, YUGABYTEDB })
public static <T> QuantifiedSelect<Record1<T>> any(T... array) {
return array instanceof Field[] ? any((Field<T>[]) array) : new QuantifiedSelectImpl<>(Quantifier.ANY, val(array));
return array instanceof Field[] ? any((Field<T>[]) array) : new QuantifiedArray<>(Quantifier.ANY, val(array));
}
/**
@ -11020,7 +11021,7 @@ public class DSL {
@NotNull
@Support({ H2, HSQLDB, POSTGRES, YUGABYTEDB })
public static <T> QuantifiedSelect<Record1<T>> any(Field<T[]> array) {
return new QuantifiedSelectImpl<>(Quantifier.ANY, array);
return new QuantifiedArray<>(Quantifier.ANY, array);
}
/**
@ -11042,7 +11043,7 @@ public class DSL {
@Support
@SafeVarargs
public static <T> QuantifiedSelect<Record1<T>> any(Field<T>... fields) {
return new QuantifiedSelectImpl<>(Quantifier.ANY, fields);
return new QuantifiedArray<>(Quantifier.ANY, new Array<>(asList(fields)));
}
// -------------------------------------------------------------------------

View File

@ -1016,6 +1016,40 @@ public final class QOM {
@NotNull default Select<?> $field() { return $arg1(); }
}
public sealed interface Quantified
extends
org.jooq.QueryPart
permits
QuantifiedSelect,
QuantifiedArray
{}
public sealed interface QuantifiedSelect<R extends Record>
extends
Quantified,
UOperator2<Quantifier, Select<R>, QuantifiedSelect<R>>
permits
org.jooq.impl.QuantifiedSelectImpl
{
@NotNull default Quantifier $quantifier() { return $arg1(); }
@NotNull default QuantifiedSelect<R> $quantifier(Quantifier newQuantifier) { return $arg1(newQuantifier); }
@NotNull default Select<R> $select() { return $arg2(); }
@NotNull default QuantifiedSelect<R> $array(Select<R> newSelect) { return $arg2(newSelect); }
}
public sealed interface QuantifiedArray<T>
extends
Quantified,
UOperator2<Quantifier, Field<T[]>, QuantifiedArray<T>>
permits
org.jooq.impl.QuantifiedArray
{
@NotNull default Quantifier $quantifier() { return $arg1(); }
@NotNull default QuantifiedArray<T> $quantifier(Quantifier newQuantifier) { return $arg1(newQuantifier); }
@NotNull default Field<T[]> $array() { return $arg2(); }
@NotNull default QuantifiedArray<T> $array(Field<T[]> newArray) { return $arg2(newArray); }
}
// -------------------------------------------------------------------------
// XXX: Rows
@ -1506,7 +1540,7 @@ public final class QOM {
/*permits
org.jooq.impl.Array*/
{
@NotNull UnmodifiableList<? extends Field<?>> $elements();
@NotNull UnmodifiableList<? extends Field<T>> $elements();
}
public /*sealed*/ interface ArrayQuery<T>
@ -8257,6 +8291,23 @@ public final class QOM {
}
}
/**
* The <code>Quantifier</code> type.
* <p>
* A quantifier for quantified selects.
*/
public enum Quantifier {
ANY(keyword("any")),
ALL(keyword("all")),
;
final Keyword keyword;
private Quantifier(Keyword keyword) {
this.keyword = keyword;
}
}
// -------------------------------------------------------------------------

View File

@ -0,0 +1,192 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: https://www.jooq.org/legal/licensing
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static java.lang.Boolean.TRUE;
// ...
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.QOM.Quantifier.ANY;
import static org.jooq.impl.SubqueryCharacteristics.PREDICAND;
import static org.jooq.impl.Tools.visitSubquery;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.Function2;
import org.jooq.Param;
import org.jooq.QuantifiedSelect;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Select;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.QOM.UNotYetImplemented;
import org.jooq.impl.Tools.BooleanDataKey;
import org.jetbrains.annotations.NotNull;
/**
* @author Lukas Eder
*/
final class QuantifiedArray<T>
extends
AbstractQueryPart
implements
QuantifiedSelect<Record1<T>>,
QOM.QuantifiedArray<T> {
final Quantifier quantifier;
final Field<T[]> array;
QuantifiedArray(Quantifier quantifier, Field<T[]> array) {
this.quantifier = quantifier;
this.array = array;
}
// ------------------------------------------------------------------------
// XXX: QueryPart API
// ------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
boolean extraParentheses = false ;
switch (ctx.family()) {
default:
ctx.visit(quantifier.keyword);
ctx.sql(extraParentheses ? " ((" : " (");
visitSubquery(ctx, delegate(ctx), PREDICAND, false);
ctx.sql(extraParentheses ? "))" : ")");
break;
}
}
private final QueryPart delegate(Context<?> ctx) {
if (array instanceof QOM.Array<T> a) {
switch (ctx.family()) {
// [#869] Postgres supports this syntax natively
case POSTGRES:
case YUGABYTEDB:
return array;
default: {
Select<Record1<T>> select = null;
for (Field<T> value : a.$elements())
if (select == null)
select = select(value);
else
select = select.unionAll(select(value));
return select;
}
}
}
else {
switch (ctx.family()) {
// [#869] Postgres supports this syntax natively
case POSTGRES:
case YUGABYTEDB:
return array;
// [#869] H2 and HSQLDB can emulate this syntax by unnesting
// the array in a subselect
case H2:
case HSQLDB:
return select().from(table(array));
// [#1048] All other dialects emulate unnesting of arrays using
// UNION ALL-connected subselects
default: {
// The Informix database has an interesting bug when quantified comparison predicates
// use nested derived tables with UNION ALL
if (array instanceof Param) {
Object[] values0 = ((Param<? extends Object[]>) array).getValue();
Select<Record1<Object>> select = null;
for (Object value : values0)
if (select == null)
select = select(val(value));
else
select = select.unionAll(select(val(value)));
return select;
}
else
return select().from(table(array));
}
}
}
}
// -------------------------------------------------------------------------
// XXX: Query Object Model
// -------------------------------------------------------------------------
@Override
public final Function2<? super Quantifier, ? super Field<T[]>, ? extends QuantifiedArray<T>> $constructor() {
return (q, a) -> new QuantifiedArray<>(q, a);
}
@Override
public final Quantifier $arg1() {
return quantifier;
}
@Override
public final Field<T[]> $arg2() {
return array;
}
}

View File

@ -80,6 +80,7 @@ import static org.jooq.impl.SQLDataType.VARCHAR;
import static org.jooq.impl.Tools.characterLiteral;
import static org.jooq.impl.Tools.embeddedFields;
import static org.jooq.impl.Tools.map;
import static org.jooq.impl.Tools.quantify;
import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable;
import static org.jooq.impl.Transformations.subqueryWithLimit;
import static org.jooq.tools.Convert.convert;
@ -99,6 +100,8 @@ import org.jooq.Record1;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.Table;
import org.jooq.impl.QOM.Array;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.QOM.UNotYetImplemented;
/**
@ -106,18 +109,18 @@ import org.jooq.impl.QOM.UNotYetImplemented;
*/
final class QuantifiedComparisonCondition extends AbstractCondition implements LikeEscapeStep, UNotYetImplemented {
private static final Clause[] CLAUSES = { CONDITION, CONDITION_BETWEEN };
private static final Set<SQLDialect> NO_SUPPORT_QUANTIFIED_LIKE = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, SQLITE);
private static final Set<SQLDialect> NO_SUPPORT_QUANTIFIED_SIMILAR_TO = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB);
private static final Set<SQLDialect> SUPPORTS_QUANTIFIED_ARRAYS = SQLDialect.supportedBy(POSTGRES);
private static final Clause[] CLAUSES = { CONDITION, CONDITION_BETWEEN };
private static final Set<SQLDialect> NO_SUPPORT_QUANTIFIED_LIKE = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, SQLITE);
private static final Set<SQLDialect> NO_SUPPORT_QUANTIFIED_SIMILAR_TO = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB);
private static final Set<SQLDialect> SUPPORTS_QUANTIFIED_ARRAYS = SQLDialect.supportedBy(POSTGRES);
private final QuantifiedSelectImpl<?> query;
private final Field<?> field;
private final Comparator comparator;
private Character escape;
private final QuantifiedSelect<?> query;
private final Field<?> field;
private final Comparator comparator;
private Character escape;
QuantifiedComparisonCondition(QuantifiedSelect<?> query, Field<?> field, Comparator comparator) {
this.query = (QuantifiedSelectImpl<?>) query;
this.query = query;
this.field = field;
this.comparator = comparator;
}
@ -137,11 +140,15 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L
ctx.visit(row(embeddedFields(field)).compare(comparator, query));
}
else if ((comparator == EQUALS || comparator == NOT_EQUALS)
&& (s = subqueryWithLimit(query.query)) != null
&& (query instanceof QOM.QuantifiedSelect)
&& (s = subqueryWithLimit(((QOM.QuantifiedSelect<?>) query).$select())) != null
&& transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) {
}
@ -157,9 +164,9 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L
accept0(ctx);
}
@SuppressWarnings({ "unchecked" })
private final void accept0(Context<?> ctx) {
boolean quantifiedArray = query.array instanceof Param<?>;
boolean quantifiedArrayParam = query instanceof QOM.QuantifiedArray<?> a ? a.$arg2() instanceof Param : false;
boolean quantifiedArray = query instanceof QOM.QuantifiedArray<?> a ? a.$arg2() instanceof Array : false;
boolean emulateOperator;
switch (comparator) {
@ -180,21 +187,23 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L
// [#9224] Special case when a SQL dialect actually supports quantified
// arrays, such as x = any(?::int[]) in PostgreSQL
if (quantifiedArray && SUPPORTS_QUANTIFIED_ARRAYS.contains(ctx.dialect()) && !emulateOperator) {
if (quantifiedArrayParam && SUPPORTS_QUANTIFIED_ARRAYS.contains(ctx.dialect()) && !emulateOperator) {
accept1(ctx);
}
else if (query.values != null || quantifiedArray) {
else if (quantifiedArrayParam || quantifiedArray) {
QOM.QuantifiedArray<?> a = (org.jooq.impl.QOM.QuantifiedArray<?>) query;
ctx.visit(DSL.condition(
query.quantifier == Quantifier.ALL ? Operator.AND : Operator.OR,
query.values != null
? map(query.values, v -> comparisonCondition(comparator, (Field<String>) v))
: map(((Param<? extends Object[]>) query.array).getValue(), v -> v instanceof Field ? comparisonCondition(comparator, (Field<String>) v) : comparisonCondition(comparator, v))
a.$quantifier() == Quantifier.ALL ? Operator.AND : Operator.OR,
a.$array() instanceof Array
? map(((Array) a.$array()).$elements(), v -> comparisonCondition(comparator, (Field<String>) v))
: map(((Param<? extends Object[]>) a.$array()).getValue(), v -> v instanceof Field ? comparisonCondition(comparator, (Field<String>) v) : comparisonCondition(comparator, v))
));
}
else if ((query.array != null || query.query != null) && emulateOperator) {
else if (emulateOperator) {
Field<String> pattern = DSL.field(name("pattern"), VARCHAR);
Condition condition;
Field<Boolean> lhs;
switch (comparator) {
case NOT_LIKE:
case NOT_SIMILAR_TO:
@ -212,11 +221,20 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L
throw new IllegalStateException();
}
Table<?> t = query.array != null
? new ArrayTable(query.array).asTable("t", "pattern")
: new AliasedSelect<>(query.query, true, true, false, name("pattern")).as("t");
Select<Record1<Boolean>> select = select(condition).from(t);
ctx.visit(lhs.eq(query.quantifier.apply(select)));
Table<?> t;
Quantifier q;
if (query instanceof QuantifiedArray<?> a) {
t = new ArrayTable(a.$array()).asTable("t", "pattern");
q = a.$quantifier();
}
else {
QOM.QuantifiedSelect<?> s = (QOM.QuantifiedSelect<?>) query;
t = new AliasedSelect<>(s.$select(), true, true, false, name("pattern")).as("t");
q = s.$quantifier();
}
ctx.visit(lhs.eq(quantify(q, select(condition).from(t))));
}
else {
accept1(ctx);

View File

@ -39,55 +39,40 @@ package org.jooq.impl;
import static java.lang.Boolean.TRUE;
// ...
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Quantifier.ANY;
import static org.jooq.impl.QOM.Quantifier.ANY;
import static org.jooq.impl.SubqueryCharacteristics.PREDICAND;
import static org.jooq.impl.Tools.visitSubquery;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.Param;
import org.jooq.Function2;
import org.jooq.QuantifiedSelect;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Select;
import org.jooq.impl.QOM.UNotYetImplemented;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.Tools.BooleanDataKey;
/**
* @author Lukas Eder
*/
final class QuantifiedSelectImpl<R extends Record> extends AbstractQueryPart implements QuantifiedSelect<R>, UNotYetImplemented {
final class QuantifiedSelectImpl<R extends Record>
extends
AbstractQueryPart
implements
QuantifiedSelect<R>,
QOM.QuantifiedSelect<R>
{
final Quantifier quantifier;
final Select<R> query;
final Field<? extends Object[]> array;
final Field<?>[] values;
final Quantifier quantifier;
final Select<R> query;
QuantifiedSelectImpl(Quantifier quantifier, Select<R> query) {
this.quantifier = quantifier;
this.query = query;
this.array = null;
this.values = null;
}
QuantifiedSelectImpl(Quantifier quantifier, Field<? extends Object[]> array) {
this.quantifier = quantifier;
this.query = null;
this.array = array;
this.values = null;
}
QuantifiedSelectImpl(Quantifier quantifier, Field<?>... values) {
this.quantifier = quantifier;
this.query = null;
this.array = null;
this.values = values;
}
// ------------------------------------------------------------------------
// XXX: QueryPart API
// ------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
@ -102,77 +87,31 @@ final class QuantifiedSelectImpl<R extends Record> extends AbstractQueryPart imp
default:
ctx.visit(quantifier.toKeyword());
ctx.visit(quantifier.keyword);
ctx.sql(extraParentheses ? " ((" : " (");
visitSubquery(ctx, delegate(ctx.configuration()), PREDICAND, false);
visitSubquery(ctx, query, PREDICAND, false);
ctx.sql(extraParentheses ? "))" : ")");
break;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private final QueryPart delegate(Configuration ctx) {
if (query != null) {
return query;
}
else if (values != null) {
Select<Record1<?>> select = null;
// -------------------------------------------------------------------------
// XXX: Query Object Model
// -------------------------------------------------------------------------
for (Field value : values)
if (select == null)
select = select(value);
else
select = select.unionAll(select(value));
@Override
public final Function2<? super Quantifier, ? super Select<R>, ? extends QOM.QuantifiedSelect<R>> $constructor() {
return (q, s) -> new QuantifiedSelectImpl<>(q, s);
}
return select;
}
else {
switch (ctx.family()) {
@Override
public final Quantifier $arg1() {
return quantifier;
}
// [#869] Postgres supports this syntax natively
case POSTGRES:
case YUGABYTEDB:
return array;
// [#869] H2 and HSQLDB can emulate this syntax by unnesting
// the array in a subselect
case H2:
case HSQLDB:
return create(ctx).select().from(table(array));
// [#1048] All other dialects emulate unnesting of arrays using
// UNION ALL-connected subselects
default: {
// The Informix database has an interesting bug when quantified comparison predicates
// use nested derived tables with UNION ALL
if (array instanceof Param) {
Object[] values0 = ((Param<? extends Object[]>) array).getValue();
Select<Record1<Object>> select = null;
for (Object value : values0)
if (select == null)
select = select(val(value));
else
select = select.unionAll(select(val(value)));
return select;
}
else {
return select().from(table(array));
}
}
}
}
@Override
public final Select<R> $arg2() {
return query;
}
}

View File

@ -1,93 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: https://www.jooq.org/legal/licensing
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.all;
import static org.jooq.impl.DSL.any;
import org.jooq.Keyword;
import org.jooq.QuantifiedSelect;
import org.jooq.Record;
import org.jooq.Select;
/**
* A quantifier used for quantified comparison predicates
*
* @author Lukas Eder
*/
enum Quantifier {
/**
* The <code>ANY</code> quantifier
*/
ANY("any"),
/**
* The <code>ALL</code> quantifier
*/
ALL("all"),
;
private final String sql;
private final Keyword keyword;
private Quantifier(String sql) {
this.sql = sql;
this.keyword = DSL.keyword(sql);
}
public final String toSQL() {
return sql;
}
public final Keyword toKeyword() {
return keyword;
}
public <R extends Record> QuantifiedSelect<R> apply(Select<R> select) {
switch (this) {
case ANY:
return any(select);
case ALL:
return all(select);
default:
throw new IllegalStateException();
}
}
}

View File

@ -48,12 +48,13 @@ import static org.jooq.impl.DSL.noCondition;
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.Quantifier.ALL;
import static org.jooq.impl.Quantifier.ANY;
import static org.jooq.impl.QOM.Quantifier.ALL;
import static org.jooq.impl.QOM.Quantifier.ANY;
import static org.jooq.impl.SubqueryCharacteristics.PREDICAND;
import static org.jooq.impl.Tools.embeddedFieldsRow;
import static org.jooq.impl.Tools.fieldNames;
import static org.jooq.impl.Tools.fieldsByName;
import static org.jooq.impl.Tools.quantify;
import static org.jooq.impl.Tools.visitSubquery;
import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable;
import static org.jooq.impl.Transformations.subqueryWithLimit;
@ -73,6 +74,7 @@ import org.jooq.Row;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.SelectOrderByStep;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.QOM.UNotYetImplemented;
import org.jooq.impl.QOM.UTransient;
import org.jooq.impl.Tools.BooleanDataKey;
@ -218,6 +220,13 @@ final class RowSubqueryCondition extends AbstractCondition implements UNotYetImp
}
else
accept0(ctx);

View File

@ -111,6 +111,8 @@ import static org.jooq.impl.DDLStatementType.DROP_SCHEMA;
import static org.jooq.impl.DDLStatementType.DROP_SEQUENCE;
import static org.jooq.impl.DDLStatementType.DROP_TABLE;
import static org.jooq.impl.DDLStatementType.DROP_VIEW;
import static org.jooq.impl.DSL.all;
import static org.jooq.impl.DSL.any;
import static org.jooq.impl.DSL.asterisk;
import static org.jooq.impl.DSL.concat;
import static org.jooq.impl.DSL.escape;
@ -298,6 +300,7 @@ import org.jooq.Param;
// ...
import org.jooq.QualifiedAsterisk;
import org.jooq.QualifiedRecord;
import org.jooq.QuantifiedSelect;
import org.jooq.Query;
import org.jooq.QueryPart;
import org.jooq.Record;
@ -343,6 +346,7 @@ import org.jooq.exception.MappingException;
import org.jooq.exception.NoDataFoundException;
import org.jooq.exception.TemplatingException;
import org.jooq.exception.TooManyRowsException;
import org.jooq.impl.QOM.Quantifier;
import org.jooq.impl.QOM.UEmpty;
import org.jooq.impl.ResultsImpl.ResultOrRowsImpl;
import org.jooq.tools.Ints;
@ -7416,4 +7420,15 @@ final class Tools {
else
return Convert.convertArray(array, type);
}
static final <R extends Record> QuantifiedSelect<R> quantify(Quantifier q, Select<R> select) {
switch (q) {
case ANY:
return any(select);
case ALL:
return all(select);
default:
throw new IllegalArgumentException("Unsupported quantifier: " + q);
}
}
}