diff --git a/jOOQ/src/main/java/org/jooq/SelectQuery.java b/jOOQ/src/main/java/org/jooq/SelectQuery.java index 260635dc84..df4e90627f 100644 --- a/jOOQ/src/main/java/org/jooq/SelectQuery.java +++ b/jOOQ/src/main/java/org/jooq/SelectQuery.java @@ -640,6 +640,13 @@ public interface SelectQuery extends Select, ConditionProvi @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) void addLimit(Param offset, Param numberOfRows); + /** + * Specify the TOP n WITH TIES or + * FETCH NEXT n WITH TIES clause. + */ + @Support({}) + void setWithTies(boolean withTies); + /** * Sets the "FOR UPDATE" flag onto the query. *

diff --git a/jOOQ/src/main/java/org/jooq/SelectWithTiesAfterOffsetStep.java b/jOOQ/src/main/java/org/jooq/SelectWithTiesAfterOffsetStep.java new file mode 100644 index 0000000000..59398af659 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/SelectWithTiesAfterOffsetStep.java @@ -0,0 +1,86 @@ +/* + * 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; + +// ... +// ... + +/** + * This type is used for the {@link Select}'s DSL API when selecting generic + * {@link Record} types. + *

+ * Example:

+ * -- 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
+ * 
Its equivalent in jOOQ
+ * 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();
+ * 
Refer to the manual for more details + * + * @author Lukas Eder + */ +public interface SelectWithTiesAfterOffsetStep extends SelectForUpdateStep { + + @Support({}) + SelectForUpdateStep withTies(); +} diff --git a/jOOQ/src/main/java/org/jooq/SelectWithTiesStep.java b/jOOQ/src/main/java/org/jooq/SelectWithTiesStep.java new file mode 100644 index 0000000000..46b4d569f5 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/SelectWithTiesStep.java @@ -0,0 +1,86 @@ +/* + * 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; + +// ... +// ... + +/** + * This type is used for the {@link Select}'s DSL API when selecting generic + * {@link Record} types. + *

+ * Example:

+ * -- 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
+ * 
Its equivalent in jOOQ
+ * 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();
+ * 
Refer to the manual for more details + * + * @author Lukas Eder + */ +public interface SelectWithTiesStep extends SelectOffsetStep { + + @Support({}) + SelectOffsetStep withTies(); +} diff --git a/jOOQ/src/main/java/org/jooq/impl/Keywords.java b/jOOQ/src/main/java/org/jooq/impl/Keywords.java index 939fdd1257..336504c484 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Keywords.java +++ b/jOOQ/src/main/java/org/jooq/impl/Keywords.java @@ -215,6 +215,7 @@ final class Keywords { static final Keyword K_ROWS = keyword("rows"); static final Keyword K_ROWS_FROM = keyword("rows from"); static final Keyword K_ROWS_ONLY = keyword("rows only"); + static final Keyword K_ROWS_WITH_TIES = keyword("rows with ties"); static final Keyword K_SELECT = keyword("select"); static final Keyword K_SEPARATOR = keyword("separator"); static final Keyword K_SEQUENCE = keyword("sequence"); @@ -269,6 +270,7 @@ final class Keywords { static final Keyword K_WITH_PRIMARY_KEY = keyword("with primary key"); static final Keyword K_WITH_READ_ONLY = keyword("with read only"); static final Keyword K_WITH_ROLLUP = keyword("with rollup"); + static final Keyword K_WITH_TIES = keyword("with ties"); static final Keyword K_WITHIN_GROUP = keyword("within group"); static final Keyword K_XMLTABLE = keyword("xmltable"); static final Keyword K_YEAR_TO_DAY = keyword("year to day"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Limit.java b/jOOQ/src/main/java/org/jooq/impl/Limit.java index b65c86efe0..7fe17a4db4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Limit.java +++ b/jOOQ/src/main/java/org/jooq/impl/Limit.java @@ -47,10 +47,12 @@ import static org.jooq.impl.Keywords.K_LIMIT; import static org.jooq.impl.Keywords.K_OFFSET; import static org.jooq.impl.Keywords.K_ROWS; import static org.jooq.impl.Keywords.K_ROWS_ONLY; +import static org.jooq.impl.Keywords.K_ROWS_WITH_TIES; import static org.jooq.impl.Keywords.K_SKIP; import static org.jooq.impl.Keywords.K_START_AT; import static org.jooq.impl.Keywords.K_TO; import static org.jooq.impl.Keywords.K_TOP; +import static org.jooq.impl.Keywords.K_WITH_TIES; import org.jooq.Clause; import org.jooq.Context; @@ -78,6 +80,7 @@ final class Limit extends AbstractQueryPart { private Field offsetOrZero = ZERO; private Field offsetPlusOne = ONE; private boolean rendersParams; + private boolean withTies; @Override public final void accept(Context context) { @@ -151,6 +154,14 @@ final class Limit extends AbstractQueryPart { + + + + + + + + case DERBY: { // Casts are not supported here... @@ -163,7 +174,7 @@ final class Limit extends AbstractQueryPart { if (!limitZero()) context.sql(' ').visit(K_FETCH_NEXT) .sql(' ').visit(numberOfRows) - .sql(' ').visit(K_ROWS_ONLY); + .sql(' ').visit(withTies ? K_ROWS_WITH_TIES : K_ROWS_ONLY); context.castMode(castMode); @@ -249,11 +260,6 @@ final class Limit extends AbstractQueryPart { - - - - - @@ -308,6 +314,20 @@ final class Limit extends AbstractQueryPart { } } + + + + + + + + + + + + + + @Override public final Clause[] clauses(Context ctx) { return null; @@ -384,4 +404,12 @@ final class Limit extends AbstractQueryPart { this.numberOfRowsOrMax = numberOfRows; this.rendersParams = true; } + + final void setWithTies(boolean withTies) { + this.withTies = withTies; + } + + final boolean withTies() { + return withTies; + } } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java index 26699a3be3..c83853a3cd 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java @@ -88,7 +88,6 @@ import org.jooq.SelectHavingConditionStep; import org.jooq.SelectIntoStep; import org.jooq.SelectJoinStep; import org.jooq.SelectLimitAfterOffsetStep; -import org.jooq.SelectOffsetStep; import org.jooq.SelectOnConditionStep; import org.jooq.SelectOnStep; import org.jooq.SelectOptionalOnStep; @@ -118,6 +117,8 @@ import org.jooq.SelectSeekStep8; import org.jooq.SelectSeekStep9; import org.jooq.SelectSeekStepN; import org.jooq.SelectSelectStep; +import org.jooq.SelectWithTiesAfterOffsetStep; +import org.jooq.SelectWithTiesStep; import org.jooq.SortField; import org.jooq.Table; import org.jooq.TableField; @@ -167,8 +168,9 @@ final class SelectImpl, SelectSeekLimitStep, - SelectOffsetStep, + SelectWithTiesStep, SelectLimitAfterOffsetStep, + SelectWithTiesAfterOffsetStep, SelectForUpdateOfStep { /** @@ -1917,6 +1919,12 @@ final class SelectImpl extends AbstractResultQuery imp + + + + + + + + + + + + + @@ -1472,6 +1485,8 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + @@ -1594,6 +1609,11 @@ final class SelectQueryImpl extends AbstractResultQuery imp getLimit().setNumberOfRows(numberOfRows); } + @Override + public final void setWithTies(boolean withTies) { + getLimit().setWithTies(withTies); + } + @Override public final void setForUpdate(boolean forUpdate) { this.forUpdate = forUpdate;