diff --git a/jOOQ/src/main/java/org/jooq/impl/Array.java b/jOOQ/src/main/java/org/jooq/impl/Array.java index a4dcea969a..56988f649c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Array.java +++ b/jOOQ/src/main/java/org/jooq/impl/Array.java @@ -120,8 +120,8 @@ final class Array extends AbstractField implements QOM.Array { // ------------------------------------------------------------------------- @Override - public final UnmodifiableList> $elements() { - return QOM.unmodifiable(fields.fields); + public final UnmodifiableList> $elements() { + return (UnmodifiableList>) QOM.unmodifiable(fields.fields); } diff --git a/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java b/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java index 28d730d7d4..b47c44fdf6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/ArrayTable.java @@ -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; diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 5a43438249..eaa3fe093c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -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 QuantifiedSelect> all(T... array) { - return array instanceof Field[] ? all((Field[]) array) : new QuantifiedSelectImpl<>(Quantifier.ALL, val(array)); + return array instanceof Field[] ? all((Field[]) array) : new QuantifiedArray<>(Quantifier.ALL, val(array)); } /** @@ -10938,7 +10939,7 @@ public class DSL { @NotNull @Support({ H2, HSQLDB, POSTGRES, YUGABYTEDB }) public static QuantifiedSelect> all(Field array) { - return new QuantifiedSelectImpl<>(Quantifier.ALL, array); + return new QuantifiedArray<>(Quantifier.ALL, array); } /** @@ -10960,7 +10961,7 @@ public class DSL { @Support @SafeVarargs public static QuantifiedSelect> all(Field... 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 QuantifiedSelect> any(T... array) { - return array instanceof Field[] ? any((Field[]) array) : new QuantifiedSelectImpl<>(Quantifier.ANY, val(array)); + return array instanceof Field[] ? any((Field[]) array) : new QuantifiedArray<>(Quantifier.ANY, val(array)); } /** @@ -11020,7 +11021,7 @@ public class DSL { @NotNull @Support({ H2, HSQLDB, POSTGRES, YUGABYTEDB }) public static QuantifiedSelect> any(Field array) { - return new QuantifiedSelectImpl<>(Quantifier.ANY, array); + return new QuantifiedArray<>(Quantifier.ANY, array); } /** @@ -11042,7 +11043,7 @@ public class DSL { @Support @SafeVarargs public static QuantifiedSelect> any(Field... fields) { - return new QuantifiedSelectImpl<>(Quantifier.ANY, fields); + return new QuantifiedArray<>(Quantifier.ANY, new Array<>(asList(fields))); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/QOM.java b/jOOQ/src/main/java/org/jooq/impl/QOM.java index 5681b5499e..0c14cf6453 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QOM.java +++ b/jOOQ/src/main/java/org/jooq/impl/QOM.java @@ -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 + extends + Quantified, + UOperator2, QuantifiedSelect> + permits + org.jooq.impl.QuantifiedSelectImpl + { + @NotNull default Quantifier $quantifier() { return $arg1(); } + @NotNull default QuantifiedSelect $quantifier(Quantifier newQuantifier) { return $arg1(newQuantifier); } + @NotNull default Select $select() { return $arg2(); } + @NotNull default QuantifiedSelect $array(Select newSelect) { return $arg2(newSelect); } + } + + public sealed interface QuantifiedArray + extends + Quantified, + UOperator2, QuantifiedArray> + permits + org.jooq.impl.QuantifiedArray + { + @NotNull default Quantifier $quantifier() { return $arg1(); } + @NotNull default QuantifiedArray $quantifier(Quantifier newQuantifier) { return $arg1(newQuantifier); } + @NotNull default Field $array() { return $arg2(); } + @NotNull default QuantifiedArray $array(Field newArray) { return $arg2(newArray); } + } + // ------------------------------------------------------------------------- // XXX: Rows @@ -1506,7 +1540,7 @@ public final class QOM { /*permits org.jooq.impl.Array*/ { - @NotNull UnmodifiableList> $elements(); + @NotNull UnmodifiableList> $elements(); } public /*sealed*/ interface ArrayQuery @@ -8257,6 +8291,23 @@ public final class QOM { } } + /** + * The Quantifier type. + *

+ * A quantifier for quantified selects. + */ + public enum Quantifier { + ANY(keyword("any")), + ALL(keyword("all")), + ; + + final Keyword keyword; + + private Quantifier(Keyword keyword) { + this.keyword = keyword; + } + } + // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java b/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java new file mode 100644 index 0000000000..1e5bd530e8 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java @@ -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 +extends + AbstractQueryPart +implements + QuantifiedSelect>, + QOM.QuantifiedArray { + + final Quantifier quantifier; + final Field array; + + QuantifiedArray(Quantifier quantifier, Field 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 a) { + switch (ctx.family()) { + + // [#869] Postgres supports this syntax natively + + + case POSTGRES: + case YUGABYTEDB: + return array; + + default: { + Select> select = null; + + for (Field 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) array).getValue(); + + Select> 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, ? extends QuantifiedArray> $constructor() { + return (q, a) -> new QuantifiedArray<>(q, a); + } + + @Override + public final Quantifier $arg1() { + return quantifier; + } + + @Override + public final Field $arg2() { + return array; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java b/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java index 2dbfe40e31..426806745d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java @@ -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 NO_SUPPORT_QUANTIFIED_LIKE = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, SQLITE); - private static final Set NO_SUPPORT_QUANTIFIED_SIMILAR_TO = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB); - private static final Set SUPPORTS_QUANTIFIED_ARRAYS = SQLDialect.supportedBy(POSTGRES); + private static final Clause[] CLAUSES = { CONDITION, CONDITION_BETWEEN }; + private static final Set NO_SUPPORT_QUANTIFIED_LIKE = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, SQLITE); + private static final Set NO_SUPPORT_QUANTIFIED_SIMILAR_TO = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB); + private static final Set 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) v)) - : map(((Param) query.array).getValue(), v -> v instanceof Field ? comparisonCondition(comparator, (Field) 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) v)) + : map(((Param) a.$array()).getValue(), v -> v instanceof Field ? comparisonCondition(comparator, (Field) v) : comparisonCondition(comparator, v)) )); } - else if ((query.array != null || query.query != null) && emulateOperator) { + else if (emulateOperator) { Field pattern = DSL.field(name("pattern"), VARCHAR); Condition condition; Field 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> 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); diff --git a/jOOQ/src/main/java/org/jooq/impl/QuantifiedSelectImpl.java b/jOOQ/src/main/java/org/jooq/impl/QuantifiedSelectImpl.java index 2e5b788671..1b287bb9ca 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QuantifiedSelectImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/QuantifiedSelectImpl.java @@ -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 extends AbstractQueryPart implements QuantifiedSelect, UNotYetImplemented { +final class QuantifiedSelectImpl +extends + AbstractQueryPart +implements + QuantifiedSelect, + QOM.QuantifiedSelect +{ - final Quantifier quantifier; - final Select query; - final Field array; - final Field[] values; + final Quantifier quantifier; + final Select query; QuantifiedSelectImpl(Quantifier quantifier, Select query) { this.quantifier = quantifier; this.query = query; - this.array = null; - this.values = null; } - QuantifiedSelectImpl(Quantifier quantifier, Field 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 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> 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, ? extends QOM.QuantifiedSelect> $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) array).getValue(); - - Select> 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 $arg2() { + return query; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Quantifier.java b/jOOQ/src/main/java/org/jooq/impl/Quantifier.java deleted file mode 100644 index c2f4fed798..0000000000 --- a/jOOQ/src/main/java/org/jooq/impl/Quantifier.java +++ /dev/null @@ -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 ANY quantifier - */ - ANY("any"), - - /** - * The ALL 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 QuantifiedSelect apply(Select select) { - switch (this) { - case ANY: - return any(select); - case ALL: - return all(select); - default: - throw new IllegalStateException(); - } - } -} diff --git a/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java b/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java index 15c257c5a5..4eb7d62df0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java @@ -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); diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 08d0eb4b98..19cc63e97b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -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 QuantifiedSelect quantify(Quantifier q, Select select) { + switch (q) { + case ANY: + return any(select); + case ALL: + return all(select); + default: + throw new IllegalArgumentException("Unsupported quantifier: " + q); + } + } }