diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java index 31d29b29a4..d41e118b53 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java @@ -54,6 +54,8 @@ import static org.jooq.impl.Tools.EMPTY_CLAUSE; import static org.jooq.impl.Tools.EMPTY_QUERYPART; import static org.jooq.impl.Tools.lazy; import static org.jooq.impl.Tools.traverseJoins; +import static org.jooq.impl.Tools.BooleanDataKey.DATA_MULTISET_CONDITION; +import static org.jooq.impl.Tools.BooleanDataKey.DATA_MULTISET_CONTENT; import static org.jooq.impl.Tools.BooleanDataKey.DATA_NESTED_SET_OPERATIONS; import static org.jooq.impl.Tools.BooleanDataKey.DATA_OMIT_CLAUSE_EVENT_EMISSION; import static org.jooq.impl.Tools.BooleanDataKey.DATA_RENDER_IMPLICIT_JOIN; @@ -106,6 +108,7 @@ import org.jooq.conf.SettingsTools; import org.jooq.conf.StatementType; import org.jooq.exception.DataAccessException; import org.jooq.impl.QOM.UEmpty; +import org.jooq.impl.Tools.BooleanDataKey; import org.jooq.impl.Tools.DataKey; @@ -263,7 +266,24 @@ abstract class AbstractContext> extends AbstractScope imple @Override public final C visit(Condition part) { - return visit((QueryPart) part); + + // [#16310] The MULTISET content flag needs to be reset for any non + // multiset projection context. For example, in any Condition. + // While Conditions can be projected, they're projecting a BOOLEAN, + // not nested records or collections + if (TRUE.equals(data(DATA_MULTISET_CONTENT))) { + try { + data(DATA_MULTISET_CONTENT, false); + visit((QueryPart) part); + } + finally { + data(DATA_MULTISET_CONTENT, true); + } + } + else + visit((QueryPart) part); + + return (C) this; } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectIsNotNull.java b/jOOQ/src/main/java/org/jooq/impl/SelectIsNotNull.java index b7d17e61ed..5134406160 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectIsNotNull.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectIsNotNull.java @@ -42,10 +42,11 @@ import static org.jooq.impl.DSL.selectCount; import static org.jooq.impl.Keywords.K_IS_NOT_NULL; import static org.jooq.impl.SubqueryCharacteristics.PREDICAND; import static org.jooq.impl.Tools.allNotNull; +import static org.jooq.impl.Tools.exactlyOne; +import static org.jooq.impl.Tools.flattenCollection; import static org.jooq.impl.Tools.visitSubquery; import org.jooq.Clause; -import org.jooq.Condition; import org.jooq.Context; import org.jooq.Function1; import org.jooq.Select; @@ -78,7 +79,8 @@ final class SelectIsNotNull extends AbstractCondition implements QOM.SelectIsNot if (SelectIsNull.EMULATE_NULL_QUERY.contains(ctx.dialect())) { // [#11011] Avoid the RVE IS NULL emulation for queries of degree 1 - if (select.getSelect().size() == 1) { + // [#16319] Flatten embeddables to find collection size + if (exactlyOne(flattenCollection(select.getSelect()))) { acceptStandard(ctx); } else { diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java b/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java index 658039e97e..95589d8a6e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java @@ -73,6 +73,8 @@ import static org.jooq.impl.DSL.selectCount; import static org.jooq.impl.Keywords.K_IS_NULL; import static org.jooq.impl.SubqueryCharacteristics.PREDICAND; import static org.jooq.impl.Tools.allNull; +import static org.jooq.impl.Tools.exactlyOne; +import static org.jooq.impl.Tools.flattenCollection; import static org.jooq.impl.Tools.visitSubquery; import java.util.Set; @@ -113,7 +115,8 @@ final class SelectIsNull extends AbstractCondition implements QOM.SelectIsNull { if (EMULATE_NULL_QUERY.contains(ctx.dialect())) { // [#11011] Avoid the RVE IS NULL emulation for queries of degree 1 - if (select.getSelect().size() == 1) { + // [#16319] Flatten embeddables to find collection size + if (exactlyOne(flattenCollection(select.getSelect()))) { acceptStandard(ctx); } else { diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 9f061eac66..e4f58e906e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -6691,6 +6691,20 @@ final class Tools { return !i.hasNext(); } + static final boolean exactlyOne(Iterable it) { + if (it == null) + return false; + else if (it instanceof Collection c) + return c.size() == 1; + + Iterator i = it.iterator(); + return i.hasNext() && true_(i.next()) && !i.hasNext(); + } + + static final boolean true_(Object o) { + return true; + } + static final boolean isNotEmpty(Object[] array) { return !isEmpty(array); }