diff --git a/jOOQ/src/main/java/org/jooq/Field.java b/jOOQ/src/main/java/org/jooq/Field.java index 36b575297d..cce0c771a3 100644 --- a/jOOQ/src/main/java/org/jooq/Field.java +++ b/jOOQ/src/main/java/org/jooq/Field.java @@ -705,6 +705,27 @@ extends // Generic predicates // ------------------------------------------------------------------------- + /** + * The BINARY_LIKE operator. + */ + @NotNull + @Support + Condition binaryLike(byte[] pattern); + + /** + * The BINARY_LIKE operator. + */ + @NotNull + @Support + Condition binaryLike(Field pattern); + + /** + * The BINARY_LIKE operator. + */ + @NotNull + @Support + Condition binaryLike(org.jooq.QuantifiedSelect> pattern); + /** * The EQ operator. */ @@ -1151,6 +1172,27 @@ extends @Support({ CLICKHOUSE, CUBRID, DERBY, DUCKDB, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, YUGABYTEDB }) Condition ne(org.jooq.QuantifiedSelect> arg2); + /** + * The NOT_BINARY_LIKE operator. + */ + @NotNull + @Support + Condition notBinaryLike(byte[] pattern); + + /** + * The NOT_BINARY_LIKE operator. + */ + @NotNull + @Support + Condition notBinaryLike(Field pattern); + + /** + * The NOT_BINARY_LIKE operator. + */ + @NotNull + @Support + Condition notBinaryLike(org.jooq.QuantifiedSelect> pattern); + /** * The NOT_EQUAL operator, an alias for the NE operator. */ @@ -2363,7 +2405,7 @@ extends * @see LikeEscapeStep#escape(char) */ @NotNull - @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB }) + @Support({ POSTGRES, YUGABYTEDB }) Condition likeIgnoreCase(Field field, char escape); /** diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java index 0848486b26..1faf1c47ff 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java @@ -401,6 +401,21 @@ implements // Generic predicates // ------------------------------------------------------------------------- + @Override + public final Condition binaryLike(byte[] pattern) { + return new BinaryLike(this, Tools.field(pattern)); + } + + @Override + public final Condition binaryLike(Field pattern) { + return new BinaryLike(this, nullSafe(pattern, getDataType())); + } + + @Override + public final Condition binaryLike(org.jooq.QuantifiedSelect> pattern) { + return new BinaryLikeQuantified(this, pattern); + } + @Override public final Condition eq(T arg2) { return new Eq<>(this, Tools.field(arg2, this)); @@ -691,6 +706,21 @@ implements return new NeQuantified<>(this, arg2); } + @Override + public final Condition notBinaryLike(byte[] pattern) { + return new NotBinaryLike(this, Tools.field(pattern)); + } + + @Override + public final Condition notBinaryLike(Field pattern) { + return new NotBinaryLike(this, nullSafe(pattern, getDataType())); + } + + @Override + public final Condition notBinaryLike(org.jooq.QuantifiedSelect> pattern) { + return new NotBinaryLikeQuantified(this, pattern); + } + @Override public final Condition notEqual(T arg2) { return ne(arg2); diff --git a/jOOQ/src/main/java/org/jooq/impl/BinaryLike.java b/jOOQ/src/main/java/org/jooq/impl/BinaryLike.java new file mode 100644 index 0000000000..6a139f0afd --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/BinaryLike.java @@ -0,0 +1,166 @@ +/* + * 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 + * Apache-2.0 license 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.*; +import static org.jooq.impl.Internal.*; +import static org.jooq.impl.Keywords.*; +import static org.jooq.impl.Names.*; +import static org.jooq.impl.SQLDataType.*; +import static org.jooq.impl.Tools.*; +import static org.jooq.impl.Tools.BooleanDataKey.*; +import static org.jooq.impl.Tools.ExtendedDataKey.*; +import static org.jooq.impl.Tools.SimpleDataKey.*; +import static org.jooq.SQLDialect.*; + +import org.jooq.*; +import org.jooq.Function1; +import org.jooq.Record; +import org.jooq.conf.ParamType; +import org.jooq.tools.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + + + +/** + * The BINARY LIKE statement. + */ +@SuppressWarnings({ "rawtypes", "unchecked", "unused" }) +final class BinaryLike +extends + AbstractCondition +implements + QOM.BinaryLike +{ + + final Field value; + final Field pattern; + + BinaryLike( + Field value, + Field pattern + ) { + + this.value = nullableIf(false, Tools.nullSafe(value, pattern.getDataType())); + this.pattern = nullableIf(false, Tools.nullSafe(pattern, value.getDataType())); + } + + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + + + + private static final Set REQUIRES_CAST_ON_LIKE = SQLDialect.supportedBy(DERBY, DUCKDB, POSTGRES, TRINO, YUGABYTEDB); + + @Override + public final void accept(Context ctx) { + + + + + + + + + Like.accept0(ctx, value, org.jooq.Comparator.LIKE, pattern, null); + } + + + + + + + + + + + + + // ------------------------------------------------------------------------- + // XXX: Query Object Model + // ------------------------------------------------------------------------- + + @Override + public final Field $arg1() { + return value; + } + + @Override + public final Field $arg2() { + return pattern; + } + + @Override + public final QOM.BinaryLike $arg1(Field newValue) { + return $constructor().apply(newValue, $arg2()); + } + + @Override + public final QOM.BinaryLike $arg2(Field newValue) { + return $constructor().apply($arg1(), newValue); + } + + @Override + public final Function2, ? super Field, ? extends QOM.BinaryLike> $constructor() { + return (a1, a2) -> new BinaryLike(a1, a2); + } + + // ------------------------------------------------------------------------- + // XXX: The Object API + // ------------------------------------------------------------------------- + + @Override + public boolean equals(Object that) { + if (that instanceof QOM.BinaryLike o) { + return + StringUtils.equals($value(), o.$value()) && + StringUtils.equals($pattern(), o.$pattern()) + ; + } + else + return super.equals(that); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/BinaryLikeQuantified.java b/jOOQ/src/main/java/org/jooq/impl/BinaryLikeQuantified.java new file mode 100644 index 0000000000..71dc1db85b --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/BinaryLikeQuantified.java @@ -0,0 +1,163 @@ +/* + * 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 + * Apache-2.0 license 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.*; +import static org.jooq.impl.Internal.*; +import static org.jooq.impl.Keywords.*; +import static org.jooq.impl.Names.*; +import static org.jooq.impl.SQLDataType.*; +import static org.jooq.impl.Tools.*; +import static org.jooq.impl.Tools.BooleanDataKey.*; +import static org.jooq.impl.Tools.ExtendedDataKey.*; +import static org.jooq.impl.Tools.SimpleDataKey.*; +import static org.jooq.SQLDialect.*; + +import org.jooq.*; +import org.jooq.Function1; +import org.jooq.Record; +import org.jooq.conf.ParamType; +import org.jooq.tools.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + + + +/** + * The BINARY LIKE statement. + */ +@SuppressWarnings({ "rawtypes", "unused" }) +final class BinaryLikeQuantified +extends + AbstractCondition +implements + QOM.BinaryLikeQuantified +{ + + final Field value; + final org.jooq.QuantifiedSelect> pattern; + + BinaryLikeQuantified( + Field value, + org.jooq.QuantifiedSelect> pattern + ) { + + this.value = nullSafeNotNull(value, (DataType) OTHER); + this.pattern = nullSafeQuantifiedSelect(pattern, value.getDataType()); + } + + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + + + + @Override + public final void accept(Context ctx) { + + + + + + + + EqQuantified.acceptCompareCondition(ctx, this, (Field) value, org.jooq.Comparator.LIKE, pattern, null); + } + + + + + + + + + + + + + // ------------------------------------------------------------------------- + // XXX: Query Object Model + // ------------------------------------------------------------------------- + + @Override + public final Field $arg1() { + return value; + } + + @Override + public final org.jooq.QuantifiedSelect> $arg2() { + return pattern; + } + + @Override + public final QOM.BinaryLikeQuantified $arg1(Field newValue) { + return $constructor().apply(newValue, $arg2()); + } + + @Override + public final QOM.BinaryLikeQuantified $arg2(org.jooq.QuantifiedSelect> newValue) { + return $constructor().apply($arg1(), newValue); + } + + @Override + public final Function2, ? super org.jooq.QuantifiedSelect>, ? extends QOM.BinaryLikeQuantified> $constructor() { + return (a1, a2) -> new BinaryLikeQuantified(a1, a2); + } + + // ------------------------------------------------------------------------- + // XXX: The Object API + // ------------------------------------------------------------------------- + + @Override + public boolean equals(Object that) { + if (that instanceof QOM.BinaryLikeQuantified o) { + return + StringUtils.equals($value(), o.$value()) && + StringUtils.equals($pattern(), o.$pattern()) + ; + } + else + return super.equals(that); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 3b29d03bea..37b644eb2d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -33391,6 +33391,60 @@ public class DSL { return new ListAgg(true, Tools.nullSafe(field), separator); } + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAgg(Field field) { + return new BinaryListAgg(false, Tools.nullSafe(field)); + } + + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAgg(Field field, byte[] separator) { + return binaryListAgg(field, inline(separator)); + } + + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAgg(Field field, Field separator) { + return new BinaryListAgg(false, Tools.nullSafe(field), separator); + } + + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAggDistinct(Field field) { + return new BinaryListAgg(true, Tools.nullSafe(field)); + } + + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAggDistinct(Field field, byte[] separator) { + return binaryListAggDistinct(field, inline(separator)); + } + + /** + * Get the aggregated concatenation for a field. + */ + @NotNull + @Support({ POSTGRES, YUGABYTEDB }) + public static OrderedAggregateFunction binaryListAggDistinct(Field field, Field separator) { + return new BinaryListAgg(true, Tools.nullSafe(field), separator); + } + /** * Get the aggregated concatenation for a field. * diff --git a/jOOQ/src/main/java/org/jooq/impl/Like.java b/jOOQ/src/main/java/org/jooq/impl/Like.java index 9b2b4289fe..e4306379da 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Like.java +++ b/jOOQ/src/main/java/org/jooq/impl/Like.java @@ -162,40 +162,50 @@ implements static final void accept0(Context ctx, Field arg1, org.jooq.Comparator op, Field arg2, Character escape) { - // [#1159] [#1725] Some dialects cannot auto-convert the LHS operand to a - // VARCHAR when applying a LIKE predicate - switch (op) { - case LIKE: - case SIMILAR_TO: - case NOT_LIKE: - case NOT_SIMILAR_TO: - if (arg1.getType() != String.class && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect())) - arg1 = castIfNeeded(arg1, String.class); - if (arg2.getType() != String.class && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect())) - arg2 = castIfNeeded(arg2, String.class); - - break; - - case LIKE_IGNORE_CASE: - case NOT_LIKE_IGNORE_CASE: - if (arg1.getType() != String.class) - arg1 = castIfNeeded(arg1, String.class); - if (arg2.getType() != String.class) - arg2 = castIfNeeded(arg2, String.class); - - break; + // [#16101] BinaryLike needs a cast in all dialects + if (arg2.getDataType().isBinary()) { + if (arg1.getDataType().isString()) + arg1 = arg1.cast(VARBINARY); + else if (!arg1.getDataType().isBinary()) + arg1 = arg1.cast(VARCHAR).cast(VARBINARY); } + else { - // [#1423] [#9889] PostgreSQL and H2 support ILIKE natively. Other dialects - // need to emulate this as LOWER(lhs) LIKE LOWER(rhs) - switch (op) { - case LIKE_IGNORE_CASE: - case NOT_LIKE_IGNORE_CASE: - if (NO_SUPPORT_ILIKE.contains(ctx.dialect())) { - arg1 = DSL.lower((Field) arg1); - arg2 = DSL.lower((Field) arg2); - op = (op == org.jooq.Comparator.LIKE_IGNORE_CASE ? org.jooq.Comparator.LIKE : org.jooq.Comparator.NOT_LIKE); - } + // [#1159] [#1725] Some dialects cannot auto-convert the LHS operand to a + // VARCHAR when applying a LIKE predicate + switch (op) { + case LIKE: + case SIMILAR_TO: + case NOT_LIKE: + case NOT_SIMILAR_TO: + if (arg1.getType() != String.class && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect())) + arg1 = castIfNeeded(arg1, String.class); + if (arg2.getType() != String.class && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect())) + arg2 = castIfNeeded(arg2, String.class); + + break; + + case LIKE_IGNORE_CASE: + case NOT_LIKE_IGNORE_CASE: + if (arg1.getType() != String.class) + arg1 = castIfNeeded(arg1, String.class); + if (arg2.getType() != String.class) + arg2 = castIfNeeded(arg2, String.class); + + break; + } + + // [#1423] [#9889] PostgreSQL and H2 support ILIKE natively. Other dialects + // need to emulate this as LOWER(lhs) LIKE LOWER(rhs) + switch (op) { + case LIKE_IGNORE_CASE: + case NOT_LIKE_IGNORE_CASE: + if (NO_SUPPORT_ILIKE.contains(ctx.dialect())) { + arg1 = DSL.lower((Field) arg1); + arg2 = DSL.lower((Field) arg2); + op = (op == org.jooq.Comparator.LIKE_IGNORE_CASE ? org.jooq.Comparator.LIKE : org.jooq.Comparator.NOT_LIKE); + } + } } boolean castRhs = castRhs(ctx, arg2); diff --git a/jOOQ/src/main/java/org/jooq/impl/NotBinaryLike.java b/jOOQ/src/main/java/org/jooq/impl/NotBinaryLike.java new file mode 100644 index 0000000000..29fd5d1506 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/NotBinaryLike.java @@ -0,0 +1,163 @@ +/* + * 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 + * Apache-2.0 license 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.*; +import static org.jooq.impl.Internal.*; +import static org.jooq.impl.Keywords.*; +import static org.jooq.impl.Names.*; +import static org.jooq.impl.SQLDataType.*; +import static org.jooq.impl.Tools.*; +import static org.jooq.impl.Tools.BooleanDataKey.*; +import static org.jooq.impl.Tools.ExtendedDataKey.*; +import static org.jooq.impl.Tools.SimpleDataKey.*; +import static org.jooq.SQLDialect.*; + +import org.jooq.*; +import org.jooq.Function1; +import org.jooq.Record; +import org.jooq.conf.ParamType; +import org.jooq.tools.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + + + +/** + * The NOT BINARY LIKE statement. + */ +@SuppressWarnings({ "rawtypes", "unchecked", "unused" }) +final class NotBinaryLike +extends + AbstractCondition +implements + QOM.NotBinaryLike +{ + + final Field value; + final Field pattern; + + NotBinaryLike( + Field value, + Field pattern + ) { + + this.value = nullableIf(false, Tools.nullSafe(value, pattern.getDataType())); + this.pattern = nullableIf(false, Tools.nullSafe(pattern, value.getDataType())); + } + + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + + + + @Override + public final void accept(Context ctx) { + + + + + + + + Like.accept0(ctx, value, org.jooq.Comparator.NOT_LIKE, pattern, null); + } + + + + + + + + + + + + + // ------------------------------------------------------------------------- + // XXX: Query Object Model + // ------------------------------------------------------------------------- + + @Override + public final Field $arg1() { + return value; + } + + @Override + public final Field $arg2() { + return pattern; + } + + @Override + public final QOM.NotBinaryLike $arg1(Field newValue) { + return $constructor().apply(newValue, $arg2()); + } + + @Override + public final QOM.NotBinaryLike $arg2(Field newValue) { + return $constructor().apply($arg1(), newValue); + } + + @Override + public final Function2, ? super Field, ? extends QOM.NotBinaryLike> $constructor() { + return (a1, a2) -> new NotBinaryLike(a1, a2); + } + + // ------------------------------------------------------------------------- + // XXX: The Object API + // ------------------------------------------------------------------------- + + @Override + public boolean equals(Object that) { + if (that instanceof QOM.NotBinaryLike o) { + return + StringUtils.equals($value(), o.$value()) && + StringUtils.equals($pattern(), o.$pattern()) + ; + } + else + return super.equals(that); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/NotBinaryLikeQuantified.java b/jOOQ/src/main/java/org/jooq/impl/NotBinaryLikeQuantified.java new file mode 100644 index 0000000000..cad8d0950d --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/NotBinaryLikeQuantified.java @@ -0,0 +1,163 @@ +/* + * 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 + * Apache-2.0 license 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.*; +import static org.jooq.impl.Internal.*; +import static org.jooq.impl.Keywords.*; +import static org.jooq.impl.Names.*; +import static org.jooq.impl.SQLDataType.*; +import static org.jooq.impl.Tools.*; +import static org.jooq.impl.Tools.BooleanDataKey.*; +import static org.jooq.impl.Tools.ExtendedDataKey.*; +import static org.jooq.impl.Tools.SimpleDataKey.*; +import static org.jooq.SQLDialect.*; + +import org.jooq.*; +import org.jooq.Function1; +import org.jooq.Record; +import org.jooq.conf.ParamType; +import org.jooq.tools.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + + + +/** + * The NOT BINARY LIKE statement. + */ +@SuppressWarnings({ "rawtypes", "unused" }) +final class NotBinaryLikeQuantified +extends + AbstractCondition +implements + QOM.NotBinaryLikeQuantified +{ + + final Field value; + final org.jooq.QuantifiedSelect> pattern; + + NotBinaryLikeQuantified( + Field value, + org.jooq.QuantifiedSelect> pattern + ) { + + this.value = nullSafeNotNull(value, (DataType) OTHER); + this.pattern = nullSafeQuantifiedSelect(pattern, value.getDataType()); + } + + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + + + + @Override + public final void accept(Context ctx) { + + + + + + + + EqQuantified.acceptCompareCondition(ctx, this, (Field) value, org.jooq.Comparator.NOT_LIKE, pattern, null); + } + + + + + + + + + + + + + // ------------------------------------------------------------------------- + // XXX: Query Object Model + // ------------------------------------------------------------------------- + + @Override + public final Field $arg1() { + return value; + } + + @Override + public final org.jooq.QuantifiedSelect> $arg2() { + return pattern; + } + + @Override + public final QOM.NotBinaryLikeQuantified $arg1(Field newValue) { + return $constructor().apply(newValue, $arg2()); + } + + @Override + public final QOM.NotBinaryLikeQuantified $arg2(org.jooq.QuantifiedSelect> newValue) { + return $constructor().apply($arg1(), newValue); + } + + @Override + public final Function2, ? super org.jooq.QuantifiedSelect>, ? extends QOM.NotBinaryLikeQuantified> $constructor() { + return (a1, a2) -> new NotBinaryLikeQuantified(a1, a2); + } + + // ------------------------------------------------------------------------- + // XXX: The Object API + // ------------------------------------------------------------------------- + + @Override + public boolean equals(Object that) { + if (that instanceof QOM.NotBinaryLikeQuantified o) { + return + StringUtils.equals($value(), o.$value()) && + StringUtils.equals($pattern(), o.$pattern()) + ; + } + else + return super.equals(that); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index bbff2085bc..22d8578f0b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -7225,8 +7225,10 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { if (peekSelectOrWith(true)) { Select select = parseWithOrSelect(); parse(')'); - LikeEscapeStep result = (not ^ notOp) ? ((Field) left).notLike(any(select)) : ((Field) left).like(any(select)); - return parseEscapeClauseIf(result); + if (binary((Field) left)) + return (not ^ notOp) ? ((Field) left).notBinaryLike(any(select)) : ((Field) left).binaryLike(any(select)); + else + return parseEscapeClauseIf((not ^ notOp) ? ((Field) left).notLike(any(select)) : ((Field) left).like(any(select))); } else { List> fields; @@ -7237,9 +7239,10 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { fields = parseList(',', c -> toField(parseConcat())); parse(')'); } - Field[] fieldArray = fields.toArray(new Field[0]); - LikeEscapeStep result = (not ^ notOp) ? ((Field) left).notLike(any(fieldArray)) : ((Field) left).like(any(fieldArray)); - return parseEscapeClauseIf(result); + if (binary((Field) left)) + return (not ^ notOp) ? ((Field) left).notBinaryLike(any((Field[]) fields.toArray(EMPTY_FIELD))) : ((Field) left).binaryLike(any((Field[]) fields.toArray(EMPTY_FIELD))); + else + return parseEscapeClauseIf((not ^ notOp) ? ((Field) left).notLike(any((Field[]) fields.toArray(EMPTY_FIELD))) : ((Field) left).like(any((Field[]) fields.toArray(EMPTY_FIELD)))); } } else if (parseKeywordIf("ALL")) { @@ -7247,8 +7250,10 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { if (peekSelectOrWith(true)) { Select select = parseWithOrSelect(); parse(')'); - LikeEscapeStep result = (not ^ notOp) ? ((Field) left).notLike(all(select)) : ((Field) left).like(all(select)); - return parseEscapeClauseIf(result); + if (binary((Field) left)) + return (not ^ notOp) ? ((Field) left).notBinaryLike(all(select)) : ((Field) left).binaryLike(all(select)); + else + return parseEscapeClauseIf((not ^ notOp) ? ((Field) left).notLike(all(select)) : ((Field) left).like(all(select))); } else { List> fields; @@ -7259,15 +7264,19 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { fields = parseList(',', c -> toField(parseConcat())); parse(')'); } - Field[] fieldArray = fields.toArray(new Field[0]); - LikeEscapeStep result = (not ^ notOp) ? ((Field) left).notLike(all(fieldArray)) : ((Field) left).like(all(fieldArray)); - return parseEscapeClauseIf(result); + if (binary((Field) left)) + return (not ^ notOp) ? ((Field) left).notBinaryLike(all((Field[]) fields.toArray(EMPTY_FIELD))) : ((Field) left).binaryLike(all((Field[]) fields.toArray(EMPTY_FIELD))); + else + return parseEscapeClauseIf((not ^ notOp) ? ((Field) left).notLike(all((Field[]) fields.toArray(EMPTY_FIELD))) : ((Field) left).like(all((Field[]) fields.toArray(EMPTY_FIELD)))); } } else { Field right = toField(parseConcat()); - LikeEscapeStep like = (not ^ notOp) ? ((Field) left).notLike(right) : ((Field) left).like(right); - return parseEscapeClauseIf(like); + + if (binary((Field) left) || binary(right)) + return (not ^ notOp) ? ((Field) left).notBinaryLike(right) : ((Field) left).binaryLike(right); + else + return parseEscapeClauseIf((not ^ notOp) ? ((Field) left).notLike(right) : ((Field) left).like(right)); } } else if (isField && (parseKeywordIf("ILIKE") || parseOperatorIf("~~*") || (notOp = parseOperatorIf("!~~*")))) { diff --git a/jOOQ/src/main/java/org/jooq/impl/QOM.java b/jOOQ/src/main/java/org/jooq/impl/QOM.java index a0aff71b41..ed5bf10ae4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QOM.java +++ b/jOOQ/src/main/java/org/jooq/impl/QOM.java @@ -2813,6 +2813,44 @@ public final class QOM { // And {} + /** + * The BINARY LIKE operator. + */ + public /*sealed*/ interface BinaryLike + extends + UReturnsNullOnNullInput, + UOperator2, Field, BinaryLike>, + org.jooq.Condition + //permits + // BinaryLike + { + @NotNull default Field $value() { return $arg1(); } + @CheckReturnValue + @NotNull default BinaryLike $value(Field newValue) { return $arg1(newValue); } + @NotNull default Field $pattern() { return $arg2(); } + @CheckReturnValue + @NotNull default BinaryLike $pattern(Field newPattern) { return $arg2(newPattern); } + } + + /** + * The BINARY LIKE operator. + */ + public /*sealed*/ interface BinaryLikeQuantified + extends + UReturnsNullOnNullInput, + UOperator2, org.jooq.QuantifiedSelect>, BinaryLikeQuantified>, + org.jooq.Condition + //permits + // BinaryLikeQuantified + { + @NotNull default Field $value() { return $arg1(); } + @CheckReturnValue + @NotNull default BinaryLikeQuantified $value(Field newValue) { return $arg1(newValue); } + @NotNull default org.jooq.QuantifiedSelect> $pattern() { return $arg2(); } + @CheckReturnValue + @NotNull default BinaryLikeQuantified $pattern(org.jooq.QuantifiedSelect> newPattern) { return $arg2(newPattern); } + } + /** * The EQ operator. */ @@ -3198,6 +3236,44 @@ public final class QOM { @NotNull default NotField $field(Field newField) { return $arg1(newField); } } + /** + * The NOT BINARY LIKE operator. + */ + public /*sealed*/ interface NotBinaryLike + extends + UReturnsNullOnNullInput, + UOperator2, Field, NotBinaryLike>, + org.jooq.Condition + //permits + // NotBinaryLike + { + @NotNull default Field $value() { return $arg1(); } + @CheckReturnValue + @NotNull default NotBinaryLike $value(Field newValue) { return $arg1(newValue); } + @NotNull default Field $pattern() { return $arg2(); } + @CheckReturnValue + @NotNull default NotBinaryLike $pattern(Field newPattern) { return $arg2(newPattern); } + } + + /** + * The NOT BINARY LIKE operator. + */ + public /*sealed*/ interface NotBinaryLikeQuantified + extends + UReturnsNullOnNullInput, + UOperator2, org.jooq.QuantifiedSelect>, NotBinaryLikeQuantified>, + org.jooq.Condition + //permits + // NotBinaryLikeQuantified + { + @NotNull default Field $value() { return $arg1(); } + @CheckReturnValue + @NotNull default NotBinaryLikeQuantified $value(Field newValue) { return $arg1(newValue); } + @NotNull default org.jooq.QuantifiedSelect> $pattern() { return $arg2(); } + @CheckReturnValue + @NotNull default NotBinaryLikeQuantified $pattern(org.jooq.QuantifiedSelect> newPattern) { return $arg2(newPattern); } + } + /** * The NOT IN operator. *