diff --git a/jOOQ/src/main/java/org/jooq/BetweenAndStepR.java b/jOOQ/src/main/java/org/jooq/BetweenAndStepR.java
new file mode 100644
index 0000000000..abfa9d51f2
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/BetweenAndStepR.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+
+/**
+ * An intermediate DSL type for the construction of a BETWEEN
+ * predicate.
+ *
+ *
XYZ*Step types directly from client code
+ * It is usually not recommended to reference any XYZ*Step types
+ * directly from client code, or assign them to local variables. When writing
+ * dynamic SQL, creating a statement's components dynamically, and passing them
+ * to the DSL API statically is usually a better choice. See the manual's
+ * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql.
+ *
+ * Drawbacks of referencing the XYZ*Step types directly:
+ *
+ * Example: Its equivalent in jOOQ
+ * -- get all authors' first and last names, and the number
+ * -- of books they've written in German, if they have written
+ * -- more than five books in German in the last three years
+ * -- (from 2011), and sort those authors by last names
+ * -- limiting results to the second and third row
+ *
+ * SELECT T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME, COUNT(*)
+ * FROM T_AUTHOR
+ * JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
+ * WHERE T_BOOK.LANGUAGE = 'DE'
+ * AND T_BOOK.PUBLISHED > '2008-01-01'
+ * GROUP BY T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME
+ * HAVING COUNT(*) > 5
+ * ORDER BY T_AUTHOR.LAST_NAME ASC NULLS FIRST
+ * LIMIT 2
+ * OFFSET 1
+ * FOR UPDATE
+ * OF FIRST_NAME, LAST_NAME
+ * NO WAIT
+ *
Refer to the manual for more details
+ *
+ * create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+ * .from(T_AUTHOR)
+ * .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+ * .where(TBook.LANGUAGE.equal("DE"))
+ * .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+ * .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ * .having(create.count().greaterThan(5))
+ * .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
+ * .limit(2)
+ * .offset(1)
+ * .forUpdate()
+ * .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ * .noWait();
+ *
+ *
XYZ*Step types directly from client code
+ * It is usually not recommended to reference any XYZ*Step types
+ * directly from client code, or assign them to local variables. When writing
+ * dynamic SQL, creating a statement's components dynamically, and passing them
+ * to the DSL API statically is usually a better choice. See the manual's
+ * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql.
+ *
+ * Drawbacks of referencing the XYZ*Step types directly:
+ *
+ * See the explicit comparison methods for details. Note, not all {@link + * Comparator} types are supported + * + * @see #eq(Record) + * @see #ne(Record) + * @see #lt(Record) + * @see #le(Record) + * @see #gt(Record) + * @see #ge(Record) + */ + @Support + Condition compare(Comparator comparator, R record); + + /** + * Compare this subquery with a subquery using a dynamic comparator. + *
+ * See the explicit comparison methods for details. Note, not all {@link + * Comparator} types are supported + * + * @see #eq(Record) + * @see #ne(Record) + * @see #lt(Record) + * @see #le(Record) + * @see #gt(Record) + * @see #ge(Record) + */ + @Support + Condition compare(Comparator comparator, Select extends R> select); + + /** + * Compare this subquery with a quantified subquery using a dynamic + * comparator. + *
+ * See the explicit comparison methods for details. Note, not all {@link + * Comparator} types are supported + * + * @see #eq(Record) + * @see #ne(Record) + * @see #lt(Record) + * @see #le(Record) + * @see #gt(Record) + * @see #ge(Record) + */ + @Support + Condition compare(Comparator comparator, QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for equality. + */ + @Support + Condition eq(R record); + + /** + * Compare this subquery with another record for equality. + */ + @Support + Condition eq(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for equality. + */ + @Support + Condition eq(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for equality. + */ + @Support + Condition equal(R record); + + /** + * Compare this subquery with another record for equality. + */ + @Support + Condition equal(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for equality. + */ + @Support + Condition equal(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for non-equality. + */ + @Support + Condition ne(R record); + + /** + * Compare this subquery with another record for non-equality. + */ + @Support + Condition ne(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for non-equality. + */ + @Support + Condition ne(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for non-equality. + */ + @Support + Condition notEqual(R record); + + /** + * Compare this subquery with another record for non-equality. + */ + @Support + Condition notEqual(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for non-equality. + */ + @Support + Condition notEqual(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition lt(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition lt(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition lt(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition lessThan(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition lessThan(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition lessThan(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition le(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition le(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition le(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition lessOrEqual(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition lessOrEqual(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition lessOrEqual(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition gt(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition gt(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition gt(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition greaterThan(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition greaterThan(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition greaterThan(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition ge(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition ge(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition ge(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a record for order. + */ + @Support + Condition greaterOrEqual(R record); + + /** + * Compare this subquery with another record for order. + */ + @Support + Condition greaterOrEqual(Select extends R> select); + + /** + * Compare this subquery with a quanitified subquery for order. + */ + @Support + Condition greaterOrEqual(QuantifiedSelect extends R> select); + + /** + * Compare this subquery with a set of records for equality. + *
+ * Note that generating dynamic SQL with arbitrary-length
+ * IN predicates can cause cursor cache contention in some
+ * databases that use unique SQL strings as a statement identifier (e.g.
+ * {@link SQLDialect#ORACLE}). In order to prevent such problems, you could
+ * use {@link Settings#isInListPadding()} to produce less distinct SQL
+ * strings (see also
+ * [#5600]), or you
+ * could avoid IN lists, and replace them with:
+ *
IN predicates on temporary tablesIN predicates on unnested array bind variables
+ * Note that generating dynamic SQL with arbitrary-length
+ * IN predicates can cause cursor cache contention in some
+ * databases that use unique SQL strings as a statement identifier (e.g.
+ * {@link SQLDialect#ORACLE}). In order to prevent such problems, you could
+ * use {@link Settings#isInListPadding()} to produce less distinct SQL
+ * strings (see also
+ * [#5600]), or you
+ * could avoid IN lists, and replace them with:
+ *
IN predicates on temporary tablesIN predicates on unnested array bind variables
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
+ * This is the same as calling
between(minValue).and(maxValue)
+ */
+ @Support
+ BetweenAndStepbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition between(R minValue, R maxValue);
+
+ /**
+ * Check if this subquery is within a range of two subqueries.
+ * between(minValue).and(maxValue)
+ */
+ @Support
+ BetweenAndStepbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition between(Select extends R> minValue, Select extends R> maxValue);
+
+ /**
+ * Check if this subquery is within a symmetric range of two records.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition betweenSymmetric(R minValue, R maxValue);
+
+ /**
+ * Check if this subquery is within a symmetric range of two subqueries.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition betweenSymmetric(Select extends R> minValue, Select extends R> maxValue);
+
+ /**
+ * Check if this subquery is not within a range of two records.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition notBetween(R minValue, R maxValue);
+
+ /**
+ * Check if this subquery is not within a range of two subqueries.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition notBetween(Select extends R> minValue, Select extends R> maxValue);
+
+ /**
+ * Check if this subquery is not within a symmetric range of two records.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition notBetweenSymmetric(R minValue, R maxValue);
+
+ /**
+ * Check if this subquery is not within a symmetric range of two subqueries.
+ */
+ @Support
+ BetweenAndStepRbetween(minValue).and(maxValue)
+ */
+ @Support
+ Condition notBetweenSymmetric(Select extends R> minValue, Select extends R> maxValue);
+
+ /**
+ * Check if the result of this subquery IS NULL
+ */
+ @Support
+ Condition isNull();
+
+ /**
+ * Check if the result of this subquery IS NOT NULL
+ */
+ @Support
+ Condition isNotNull();
+}
diff --git a/jOOQ/src/main/java/org/jooq/SelectUnionStep.java b/jOOQ/src/main/java/org/jooq/SelectUnionStep.java
index 77c2046967..fdfae2c64f 100644
--- a/jOOQ/src/main/java/org/jooq/SelectUnionStep.java
+++ b/jOOQ/src/main/java/org/jooq/SelectUnionStep.java
@@ -123,7 +123,7 @@ import static org.jooq.SQLDialect.SQLITE;
*
* @author Lukas Eder
*/
-public interface SelectUnionStepUNION set operation.
diff --git a/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java b/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java
index 0c8e61bdb3..10c4e8a324 100644
--- a/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java
+++ b/jOOQ/src/main/java/org/jooq/impl/RowIsNull.java
@@ -43,6 +43,7 @@ import static org.jooq.Clause.CONDITION_IS_NULL;
// ...
// ...
// ...
+// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@@ -55,13 +56,18 @@ import static org.jooq.SQLDialect.MARIADB;
// ...
import static org.jooq.SQLDialect.MYSQL;
// ...
+import static org.jooq.SQLDialect.POSTGRES;
+// ...
// ...
import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
// ...
+import static org.jooq.impl.DSL.inline;
+import static org.jooq.impl.DSL.selectCount;
import static org.jooq.impl.Keywords.K_IS_NOT_NULL;
import static org.jooq.impl.Keywords.K_IS_NULL;
+import static org.jooq.impl.Tools.fieldNameStrings;
import java.util.ArrayList;
import java.util.List;
@@ -69,12 +75,12 @@ import java.util.Set;
import org.jooq.Clause;
import org.jooq.Condition;
-import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
-import org.jooq.QueryPartInternal;
import org.jooq.Row;
import org.jooq.SQLDialect;
+import org.jooq.Select;
+import org.jooq.Table;
/**
* @author Lukas Eder
@@ -84,71 +90,76 @@ final class RowIsNull extends AbstractCondition {
/**
* Generated UID
*/
- private static final long serialVersionUID = -1806139685201770706L;
- private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_IS_NULL };
- private static final Clause[] CLAUSES_NOT_NULL = { CONDITION, CONDITION_IS_NOT_NULL };
+ private static final long serialVersionUID = -1806139685201770706L;
+ private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_IS_NULL };
+ private static final Clause[] CLAUSES_NOT_NULL = { CONDITION, CONDITION_IS_NOT_NULL };
// Currently not yet supported in SQLite:
// https://www.sqlite.org/rowvalue.html
- private static final Set