diff --git a/jOOQ/src/main/java/org/jooq/Field.java b/jOOQ/src/main/java/org/jooq/Field.java
index b26e9d0d85..ee641853d2 100644
--- a/jOOQ/src/main/java/org/jooq/Field.java
+++ b/jOOQ/src/main/java/org/jooq/Field.java
@@ -1627,6 +1627,68 @@ extends
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
Condition notLikeIgnoreCase(String value, char escape);
+ /**
+ * Create a condition to pattern-check this field against any element in an array of values.
+ *
+ * SQL: (this like value0 or this like value1 or ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ LikeEscapeStep likeAny(String... values);
+
+ /**
+ * Create a condition to pattern-check this field against any element in an array of fields.
+ *
+ * SQL: (this like field0 or this like field1 or ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ @SuppressWarnings("unchecked")
+ LikeEscapeStep likeAny(Field... fields);
+
+ /**
+ * Create a condition to pattern-check this field against any element in a collection of fields or values.
+ *
+ * SQL: (this like field0 or this like field1 or ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ LikeEscapeStep likeAny(Collection> values);
+
+ /**
+ * Create a condition to pattern-check this field against all elements in an array of values.
+ *
+ * SQL: (this not like value0 and this not like value1 and ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ LikeEscapeStep notLikeAll(String... values);
+
+ /**
+ * Create a condition to pattern-check this field against all elements in an array of fields.
+ *
+ * SQL: (this not like field0 and this not like field1 and ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ @SuppressWarnings("unchecked")
+ LikeEscapeStep notLikeAll(Field... fields);
+
+ /**
+ * Create a condition to pattern-check this field against all elements in a collection of fields or values.
+ *
+ * SQL: (this not like field0 and this not like field1 and ...)
+ *
+ * @see LikeEscapeStep#escape(char)
+ */
+ @Support
+ LikeEscapeStep notLikeAll(Collection> values);
+
/**
* Convenience method for {@link #like(String, char)} including proper
* adding of wildcards and escaping.
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java
index 4764974d83..05f57ea6a5 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java
@@ -852,6 +852,40 @@ abstract class AbstractField extends AbstractNamed implements Field {
return notLikeIgnoreCase(field).escape(escape);
}
+ @Override
+ public final LikeEscapeStep likeAny(String... values) {
+ return likeAny(Tools.fields(values));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final LikeEscapeStep likeAny(Field... fields) {
+ return likeAny(Arrays.asList(fields));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final LikeEscapeStep likeAny(Collection> values) {
+ return new CombinedCompareCondition(this, LIKE, Quantifier.ANY, (Collection extends Field>) Tools.fields(values, SQLDataType.VARCHAR));
+ }
+
+ @Override
+ public final LikeEscapeStep notLikeAll(String... values) {
+ return notLikeAll(Tools.fields(values));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final LikeEscapeStep notLikeAll(Field... fields) {
+ return notLikeAll(Arrays.asList(fields));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final LikeEscapeStep notLikeAll(Collection> values) {
+ return new CombinedCompareCondition(this, NOT_LIKE, Quantifier.ALL, (Collection extends Field>) Tools.fields(values, SQLDataType.VARCHAR));
+ }
+
@Override
public final Condition notLikeRegex(String pattern) {
return likeRegex(pattern).not();
diff --git a/jOOQ/src/main/java/org/jooq/impl/CombinedCompareCondition.java b/jOOQ/src/main/java/org/jooq/impl/CombinedCompareCondition.java
new file mode 100644
index 0000000000..5ba9928271
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/CombinedCompareCondition.java
@@ -0,0 +1,116 @@
+/*
+ * 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
+ *
+ * http://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: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jooq.Comparator;
+import org.jooq.Condition;
+import org.jooq.Context;
+import org.jooq.Field;
+import org.jooq.LikeEscapeStep;
+import org.jooq.Operator;
+
+final class CombinedCompareCondition extends AbstractCondition implements LikeEscapeStep {
+
+ private static final long serialVersionUID = 1850816878293293314L;
+
+ private final Field> field;
+ private final Comparator comparator;
+ private final Quantifier quantifier;
+ private final Collection extends Field> values;
+ private Character escape;
+
+ public CombinedCompareCondition(Field> field, Comparator comparator, Quantifier quantifier, Collection extends Field> values) {
+ this.field = field;
+ this.comparator = comparator;
+ this.quantifier = quantifier;
+ this.values = values;
+ }
+
+ @Override
+ public final Condition escape(char c) {
+ this.escape = c;
+ return this;
+ }
+
+ @Override
+ public final void accept(Context> ctx) {
+ Collection conditions = new ArrayList();
+
+ switch (comparator) {
+ case LIKE:
+ for (Field value : values)
+ conditions.add(escape != null ? field.like(value, escape) : field.like(value));
+ break;
+
+ case NOT_LIKE:
+ for (Field value : values)
+ conditions.add(escape != null ? field.notLike(value, escape) : field.notLike(value));
+ break;
+
+ case SIMILAR_TO:
+ for (Field value : values)
+ conditions.add(escape != null ? field.similarTo(value, escape) : field.similarTo(value));
+ break;
+
+ case NOT_SIMILAR_TO:
+ for (Field value : values)
+ conditions.add(escape != null ? field.notSimilarTo(value, escape) : field.notSimilarTo(value));
+ break;
+
+ case LIKE_IGNORE_CASE:
+ for (Field value : values)
+ conditions.add(escape != null ? field.likeIgnoreCase(value, escape) : field.likeIgnoreCase(value));
+ break;
+
+ case NOT_LIKE_IGNORE_CASE:
+ for (Field value : values)
+ conditions.add(escape != null ? field.notLikeIgnoreCase(value, escape) : field.notLikeIgnoreCase(value));
+ break;
+
+ default:
+ break;
+ }
+
+ Condition combinedCondition = CombinedCondition.of(quantifier == Quantifier.ALL ? Operator.AND : Operator.OR, conditions);
+ ctx.visit(combinedCondition);
+ }
+
+}
diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
index 7ec4830d2f..efb074bc02 100644
--- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
@@ -400,6 +400,7 @@ import org.jooq.InsertValuesStepN;
import org.jooq.JoinType;
import org.jooq.Keyword;
// ...
+import org.jooq.LikeEscapeStep;
// ...
import org.jooq.Merge;
import org.jooq.MergeFinalStep;
@@ -4388,16 +4389,54 @@ final class ParserImpl implements Parser {
: ((RowN) left).between((RowN) r1, (RowN) r2);
}
else if (left instanceof Field && parseKeywordIf(ctx, "LIKE")) {
- Field right = toField(ctx, parseConcat(ctx, null));
- boolean escape = parseKeywordIf(ctx, "ESCAPE");
- char character = escape ? parseCharacterLiteral(ctx) : ' ';
- return escape
- ? not
- ? ((Field) left).notLike(right, character)
- : ((Field) left).like(right, character)
- : not
- ? ((Field) left).notLike(right)
- : ((Field) left).like(right);
+ if (!not && parseKeywordIf(ctx, "ANY")) {
+ parse(ctx, '(');
+ List> fields = null;
+ if (parseIf(ctx, ')'))
+ fields = Collections.> emptyList();
+ else {
+ fields = new ArrayList>();
+ do {
+ fields.add(toField(ctx, parseConcat(ctx, null)));
+ }
+ while (parseIf(ctx, ','));
+ parse(ctx, ')');
+ }
+ boolean escape = parseKeywordIf(ctx, "ESCAPE");
+ char character = escape ? parseCharacterLiteral(ctx) : ' ';
+ LikeEscapeStep result = ((Field) left).likeAny(fields);
+ return escape ? result.escape(character) : result;
+ }
+ else if (not && parseKeywordIf(ctx, "ALL")) {
+ parse(ctx, '(');
+ List> fields = null;
+ if (parseIf(ctx, ')'))
+ fields = Collections.> emptyList();
+ else {
+ fields = new ArrayList>();
+ do {
+ fields.add(toField(ctx, parseConcat(ctx, null)));
+ }
+ while (parseIf(ctx, ','));
+ parse(ctx, ')');
+ }
+ boolean escape = parseKeywordIf(ctx, "ESCAPE");
+ char character = escape ? parseCharacterLiteral(ctx) : ' ';
+ LikeEscapeStep result = ((Field) left).notLikeAll(fields);
+ return escape ? result.escape(character) : result;
+ }
+ else {
+ Field right = toField(ctx, parseConcat(ctx, null));
+ boolean escape = parseKeywordIf(ctx, "ESCAPE");
+ char character = escape ? parseCharacterLiteral(ctx) : ' ';
+ return escape
+ ? not
+ ? ((Field) left).notLike(right, character)
+ : ((Field) left).like(right, character)
+ : not
+ ? ((Field) left).notLike(right)
+ : ((Field) left).like(right);
+ }
}
else if (left instanceof Field && parseKeywordIf(ctx, "ILIKE")) {
Field right = toField(ctx, parseConcat(ctx, null));
@@ -6128,6 +6167,7 @@ final class ParserImpl implements Parser {
+
default:
Field> base = toField(ctx, parseNumericOp(ctx, N));
parse(ctx, ',');