[#7839] Emulate { UPDATE | DELETE } ORDER BY and LIMIT
This commit is contained in:
parent
5c14d8026d
commit
6164cedbd1
@ -37,10 +37,6 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
/**
|
||||
* This type is used for the {@link Delete}'s DSL API.
|
||||
* <p>
|
||||
@ -75,14 +71,14 @@ import static org.jooq.SQLDialect.MYSQL;
|
||||
public interface DeleteLimitStep<R extends Record> extends DeleteReturningStep<R> {
|
||||
|
||||
/**
|
||||
* Add a <code>LIMIT</code> clause to the query
|
||||
* Add a <code>LIMIT</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
DeleteReturningStep<R> limit(Number numberOfRows);
|
||||
|
||||
/**
|
||||
* Add a <code>LIMIT</code> clause to the query using named parameters
|
||||
* Add a <code>LIMIT</code> clause to the query using named parameters.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
DeleteReturningStep<R> limit(Param<? extends Number> numberOfRows);
|
||||
}
|
||||
@ -37,10 +37,6 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@ -77,19 +73,19 @@ import java.util.Collection;
|
||||
public interface DeleteOrderByStep<R extends Record> extends DeleteLimitStep<R> {
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
DeleteLimitStep<R> orderBy(OrderField<?>... fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
DeleteLimitStep<R> orderBy(Collection<? extends OrderField<?>> fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
* <p>
|
||||
* Indexes start at <code>1</code> in SQL!
|
||||
* <p>
|
||||
@ -97,6 +93,6 @@ public interface DeleteOrderByStep<R extends Record> extends DeleteLimitStep<R>
|
||||
* <code>orderBy(DSL.literal(1).desc())</code> to apply descending
|
||||
* ordering
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
DeleteLimitStep<R> orderBy(int... fieldIndexes);
|
||||
}
|
||||
@ -38,12 +38,9 @@
|
||||
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
@ -109,7 +106,7 @@ public interface DeleteQuery<R extends Record> extends ConditionProvider, Delete
|
||||
*
|
||||
* @param fields The ordering fields
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addOrderBy(OrderField<?>... fields);
|
||||
|
||||
/**
|
||||
@ -117,7 +114,7 @@ public interface DeleteQuery<R extends Record> extends ConditionProvider, Delete
|
||||
*
|
||||
* @param fields The ordering fields
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addOrderBy(Collection<? extends OrderField<?>> fields);
|
||||
|
||||
/**
|
||||
@ -125,7 +122,7 @@ public interface DeleteQuery<R extends Record> extends ConditionProvider, Delete
|
||||
*
|
||||
* @param numberOfRows The number of rows to return
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addLimit(Number numberOfRows);
|
||||
|
||||
/**
|
||||
@ -133,7 +130,7 @@ public interface DeleteQuery<R extends Record> extends ConditionProvider, Delete
|
||||
*
|
||||
* @param numberOfRows The number of rows to return
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addLimit(Param<? extends Number> numberOfRows);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -37,10 +37,6 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
/**
|
||||
* This type is used for the {@link Update}'s DSL API.
|
||||
* <p>
|
||||
@ -77,15 +73,15 @@ import static org.jooq.SQLDialect.MYSQL;
|
||||
public interface UpdateLimitStep<R extends Record> extends UpdateReturningStep<R> {
|
||||
|
||||
/**
|
||||
* Add a <code>LIMIT</code> clause to the query
|
||||
* Add a <code>LIMIT</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
UpdateReturningStep<R> limit(Number numberOfRows);
|
||||
|
||||
/**
|
||||
* Add a <code>LIMIT</code> clause to the query using named parameters
|
||||
* Add a <code>LIMIT</code> clause to the query using named parameters.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
UpdateReturningStep<R> limit(Param<? extends Number> numberOfRows);
|
||||
|
||||
|
||||
|
||||
@ -37,10 +37,6 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@ -79,19 +75,19 @@ import java.util.Collection;
|
||||
public interface UpdateOrderByStep<R extends Record> extends UpdateLimitStep<R> {
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
UpdateLimitStep<R> orderBy(OrderField<?>... fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
UpdateLimitStep<R> orderBy(Collection<? extends OrderField<?>> fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
* Add an <code>ORDER BY</code> clause to the query.
|
||||
* <p>
|
||||
* Indexes start at <code>1</code> in SQL!
|
||||
* <p>
|
||||
@ -99,7 +95,7 @@ public interface UpdateOrderByStep<R extends Record> extends UpdateLimitStep<R>
|
||||
* <code>orderBy(DSL.literal(1).desc())</code> to apply descending
|
||||
* ordering
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
UpdateLimitStep<R> orderBy(int... fieldIndexes);
|
||||
|
||||
}
|
||||
|
||||
@ -38,7 +38,6 @@
|
||||
|
||||
package org.jooq;
|
||||
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
@ -46,8 +45,6 @@ import static org.jooq.SQLDialect.H2;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
@ -419,7 +416,7 @@ public interface UpdateQuery<R extends Record> extends StoreQuery<R>, ConditionP
|
||||
*
|
||||
* @param fields The ordering fields
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addOrderBy(OrderField<?>... fields);
|
||||
|
||||
/**
|
||||
@ -427,7 +424,7 @@ public interface UpdateQuery<R extends Record> extends StoreQuery<R>, ConditionP
|
||||
*
|
||||
* @param fields The ordering fields
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addOrderBy(Collection<? extends OrderField<?>> fields);
|
||||
|
||||
/**
|
||||
@ -435,7 +432,7 @@ public interface UpdateQuery<R extends Record> extends StoreQuery<R>, ConditionP
|
||||
*
|
||||
* @param numberOfRows The number of rows to return
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addLimit(Number numberOfRows);
|
||||
|
||||
/**
|
||||
@ -443,7 +440,7 @@ public interface UpdateQuery<R extends Record> extends StoreQuery<R>, ConditionP
|
||||
*
|
||||
* @param numberOfRows The number of rows to return
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL })
|
||||
@Support
|
||||
void addLimit(Param<? extends Number> numberOfRows);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -43,9 +43,32 @@ import static org.jooq.Clause.DELETE_DELETE;
|
||||
import static org.jooq.Clause.DELETE_RETURNING;
|
||||
import static org.jooq.Clause.DELETE_WHERE;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
// ...
|
||||
// ...
|
||||
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.conf.SettingsTools.getExecuteDeleteWithoutWhere;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.Keywords.K_DELETE;
|
||||
import static org.jooq.impl.Keywords.K_FROM;
|
||||
import static org.jooq.impl.Keywords.K_LIMIT;
|
||||
@ -67,6 +90,8 @@ import org.jooq.Param;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.UniqueKey;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -76,10 +101,11 @@ final class DeleteQueryImpl<R extends Record> extends AbstractDMLQuery<R> implem
|
||||
private static final long serialVersionUID = -1943687511774150929L;
|
||||
private static final Clause[] CLAUSES = { DELETE };
|
||||
private static final EnumSet<SQLDialect> SPECIAL_DELETE_AS_SYNTAX = EnumSet.of(MARIADB, MYSQL);
|
||||
private static final EnumSet<SQLDialect> NO_SUPPORT_LIMIT = EnumSet.of(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, POSTGRES, SQLITE);
|
||||
|
||||
private final ConditionProviderImpl condition;
|
||||
private final SortFieldList orderBy;
|
||||
private Param<?> limit;
|
||||
private Param<? extends Number> limit;
|
||||
|
||||
DeleteQueryImpl(Configuration configuration, WithImpl with, Table<R> table) {
|
||||
super(configuration, with, table);
|
||||
@ -167,25 +193,45 @@ final class DeleteQueryImpl<R extends Record> extends AbstractDMLQuery<R> implem
|
||||
.declareTables(true)
|
||||
.visit(table)
|
||||
.declareTables(declare)
|
||||
.end(DELETE_DELETE)
|
||||
.start(DELETE_WHERE);
|
||||
.end(DELETE_DELETE);
|
||||
|
||||
if (hasWhere())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ')
|
||||
.visit(getWhere());
|
||||
if (limit != null && NO_SUPPORT_LIMIT.contains(ctx.family()) && !table.getKeys().isEmpty()) {
|
||||
UniqueKey<?> key = table.getPrimaryKey() != null ? table.getPrimaryKey() : table.getKeys().get(0);
|
||||
|
||||
ctx.end(DELETE_WHERE);
|
||||
@SuppressWarnings("unchecked")
|
||||
TableField<?, Object>[] keyFields = (TableField<?, Object>[]) key.getFieldsArray();
|
||||
|
||||
if (!orderBy.isEmpty())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_ORDER_BY).sql(' ')
|
||||
.visit(orderBy);
|
||||
ctx.start(DELETE_WHERE)
|
||||
.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ');
|
||||
|
||||
if (limit != null)
|
||||
ctx.formatSeparator()
|
||||
.visit(K_LIMIT).sql(' ')
|
||||
.visit(limit);
|
||||
if (keyFields.length == 1)
|
||||
ctx.visit(keyFields[0].in(select(keyFields[0]).from(table).where(getWhere()).orderBy(orderBy).limit(limit)));
|
||||
else
|
||||
ctx.visit(row(keyFields).in(select(keyFields).from(table).where(getWhere()).orderBy(orderBy).limit(limit)));
|
||||
|
||||
ctx.end(DELETE_WHERE);
|
||||
}
|
||||
else {
|
||||
ctx.start(DELETE_WHERE);
|
||||
|
||||
if (hasWhere())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ')
|
||||
.visit(getWhere());
|
||||
|
||||
ctx.end(DELETE_WHERE);
|
||||
|
||||
if (!orderBy.isEmpty())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_ORDER_BY).sql(' ')
|
||||
.visit(orderBy);
|
||||
|
||||
if (limit != null)
|
||||
ctx.formatSeparator()
|
||||
.visit(K_LIMIT).sql(' ')
|
||||
.visit(limit);
|
||||
}
|
||||
|
||||
ctx.start(DELETE_RETURNING);
|
||||
toSQLReturning(ctx);
|
||||
|
||||
@ -47,17 +47,28 @@ import static org.jooq.Clause.UPDATE_UPDATE;
|
||||
import static org.jooq.Clause.UPDATE_WHERE;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.POSTGRES_10;
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.conf.SettingsTools.getExecuteUpdateWithoutWhere;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.Keywords.K_FROM;
|
||||
import static org.jooq.impl.Keywords.K_LIMIT;
|
||||
@ -130,7 +141,9 @@ import org.jooq.RowN;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.TableLike;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.UpdateQuery;
|
||||
|
||||
/**
|
||||
@ -144,6 +157,7 @@ final class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
|
||||
|
||||
|
||||
private static final EnumSet<SQLDialect> SUPPORT_RVE_SET = EnumSet.of(H2, HSQLDB, POSTGRES);
|
||||
private static final EnumSet<SQLDialect> NO_SUPPORT_LIMIT = EnumSet.of(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, POSTGRES, SQLITE);
|
||||
|
||||
private final FieldMapForUpdate updateMap;
|
||||
private final TableList from;
|
||||
@ -152,7 +166,7 @@ final class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
|
||||
private Row multiValue;
|
||||
private Select<?> multiSelect;
|
||||
private final SortFieldList orderBy;
|
||||
private Param<?> limit;
|
||||
private Param<? extends Number> limit;
|
||||
|
||||
UpdateQueryImpl(Configuration configuration, WithImpl with, Table<R> table) {
|
||||
super(configuration, with, table);
|
||||
@ -629,24 +643,43 @@ final class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.start(UPDATE_WHERE);
|
||||
if (limit != null && NO_SUPPORT_LIMIT.contains(ctx.family()) && !table.getKeys().isEmpty()) {
|
||||
UniqueKey<?> key = table.getPrimaryKey() != null ? table.getPrimaryKey() : table.getKeys().get(0);
|
||||
|
||||
if (hasWhere())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ')
|
||||
.visit(getWhere());
|
||||
@SuppressWarnings("unchecked")
|
||||
TableField<?, Object>[] keyFields = (TableField<?, Object>[]) key.getFieldsArray();
|
||||
|
||||
ctx.end(UPDATE_WHERE);
|
||||
ctx.start(UPDATE_WHERE)
|
||||
.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ');
|
||||
|
||||
if (!orderBy.isEmpty())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_ORDER_BY).sql(' ')
|
||||
.visit(orderBy);
|
||||
if (keyFields.length == 1)
|
||||
ctx.visit(keyFields[0].in(select(keyFields[0]).from(table).where(getWhere()).orderBy(orderBy).limit(limit)));
|
||||
else
|
||||
ctx.visit(row(keyFields).in(select(keyFields).from(table).where(getWhere()).orderBy(orderBy).limit(limit)));
|
||||
|
||||
if (limit != null)
|
||||
ctx.formatSeparator()
|
||||
.visit(K_LIMIT).sql(' ')
|
||||
.visit(limit);
|
||||
ctx.end(UPDATE_WHERE);
|
||||
}
|
||||
else {
|
||||
ctx.start(UPDATE_WHERE);
|
||||
|
||||
if (hasWhere())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ')
|
||||
.visit(getWhere());
|
||||
|
||||
ctx.end(UPDATE_WHERE);
|
||||
|
||||
if (!orderBy.isEmpty())
|
||||
ctx.formatSeparator()
|
||||
.visit(K_ORDER_BY).sql(' ')
|
||||
.visit(orderBy);
|
||||
|
||||
if (limit != null)
|
||||
ctx.formatSeparator()
|
||||
.visit(K_LIMIT).sql(' ')
|
||||
.visit(limit);
|
||||
}
|
||||
|
||||
ctx.start(UPDATE_RETURNING);
|
||||
toSQLReturning(ctx);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user