diff --git a/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java b/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java
index 43396fab9..93d91a94c 100644
--- a/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java
+++ b/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java
@@ -75,6 +75,11 @@ public class DatabasePlatform {
protected boolean caseSensitiveCollation = true;
+ /**
+ * Set true if the Database support LIMIT clause on sql update.
+ */
+ protected boolean inlineSqlUpdateLimit;
+
/**
* For limit/offset, row_number etc limiting of SQL queries.
*/
@@ -171,7 +176,7 @@ public class DatabasePlatform {
/**
* Characters escaped for startsWith, endsWith and contains.
*/
- protected char[] likeSpecialCharacters = { '%', '_', '|' };
+ protected char[] likeSpecialCharacters = {'%', '_', '|'};
protected DbEncrypt dbEncrypt;
@@ -187,7 +192,7 @@ public class DatabasePlatform {
/**
* If set then use the CONCUR_UPDATABLE hint when creating ResultSets.
- *
+ *
* This is {@code false} for HANA
*/
protected boolean supportsResultSetConcurrencyModeUpdatable = true;
@@ -339,6 +344,13 @@ public class DatabasePlatform {
return supportsSavepointId;
}
+ /**
+ * Return true if the platform supports LIMIT with sql update.
+ */
+ public boolean isInlineSqlUpdateLimit() {
+ return inlineSqlUpdateLimit;
+ }
+
/**
* Return the maximum table name length.
*
@@ -370,11 +382,11 @@ public class DatabasePlatform {
/**
* Return a DB Sequence based IdGenerator.
*
- * @param be the BackgroundExecutor that can be used to load the sequence if
- * desired
- * @param ds the DataSource
- * @param stepSize the sequence allocation size as defined by mapping (defaults to 50)
- * @param seqName the name of the sequence
+ * @param be the BackgroundExecutor that can be used to load the sequence if
+ * desired
+ * @param ds the DataSource
+ * @param stepSize the sequence allocation size as defined by mapping (defaults to 50)
+ * @param seqName the name of the sequence
*/
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
return null;
@@ -659,7 +671,7 @@ public class DatabasePlatform {
if (dbName != null && !dbName.isEmpty()) {
if (dbName.startsWith(openQuote)) {
// trim off the open and close quotes
- return dbName.substring(1, dbName.length()-1);
+ return dbName.substring(1, dbName.length() - 1);
}
}
return dbName;
@@ -786,7 +798,7 @@ public class DatabasePlatform {
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
boolean escaped = false;
- for (char escapeChar: likeSpecialCharacters) {
+ for (char escapeChar : likeSpecialCharacters) {
if (ch == escapeChar) {
if (sb == null) {
sb = new StringBuilder(value.substring(0, i));
diff --git a/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java b/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java
index b7a3b1660..dd0cfde1a 100644
--- a/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java
+++ b/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java
@@ -24,6 +24,7 @@ public class H2Platform extends DatabasePlatform {
this.historySupport = new H2HistorySupport();
this.nativeUuidType = true;
this.supportsDeleteTableAlias = true;
+ this.inlineSqlUpdateLimit = true;
this.dbDefaultValue.setNow("now()");
this.columnAliasPrefix = null;
this.exceptionTranslator =
diff --git a/src/main/java/io/ebean/config/dbplatform/mysql/MySqlPlatform.java b/src/main/java/io/ebean/config/dbplatform/mysql/MySqlPlatform.java
index 07698f832..dd9017816 100644
--- a/src/main/java/io/ebean/config/dbplatform/mysql/MySqlPlatform.java
+++ b/src/main/java/io/ebean/config/dbplatform/mysql/MySqlPlatform.java
@@ -28,6 +28,7 @@ public class MySqlPlatform extends DatabasePlatform {
this.useExtraTransactionOnIterateSecondaryQueries = true;
this.selectCountWithAlias = true;
this.supportsSavepointId = false;
+ this.inlineSqlUpdateLimit = true;
this.dbEncrypt = new MySqlDbEncrypt();
this.historySupport = new MySqlHistorySupport();
this.columnAliasPrefix = null;
diff --git a/src/main/java/io/ebeaninternal/api/SpiQuery.java b/src/main/java/io/ebeaninternal/api/SpiQuery.java
index fd8c7ce28..9130ac67c 100644
--- a/src/main/java/io/ebeaninternal/api/SpiQuery.java
+++ b/src/main/java/io/ebeaninternal/api/SpiQuery.java
@@ -458,7 +458,7 @@ public interface SpiQuery extends Query, TxnProfileEventCodes {
/**
* Set the query to be a delete query.
*/
- void setDelete();
+ void setupForDeleteOrUpdate(boolean deleteRequest);
/**
* Set the query to be delete by ids due to cascading delete.
diff --git a/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java b/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java
index fab12b976..7394065dc 100644
--- a/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java
+++ b/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java
@@ -795,4 +795,11 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery
dependentTables.addAll(tables);
}
}
+
+ /**
+ * Return true if no MaxRows or use LIMIT in SQL update.
+ */
+ public boolean isInlineSqlUpdateLimit() {
+ return query.getMaxRows() < 1 || ebeanServer.getDatabasePlatform().isInlineSqlUpdateLimit();
+ }
}
diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
index 557499fe7..552d3d03c 100644
--- a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
+++ b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
@@ -47,24 +47,19 @@ class CQueryBuilder {
final String columnAliasPrefix;
private final SqlLimiter sqlLimiter;
-
private final CQueryBuilderRawSql rawSqlHandler;
-
private final Binder binder;
private final boolean selectCountWithAlias;
private final CQueryHistorySupport historySupport;
-
private final CQueryDraftSupport draftSupport;
-
private final DatabasePlatform dbPlatform;
/**
* Create the SqlGenSelect.
*/
CQueryBuilder(DatabasePlatform dbPlatform, Binder binder, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
-
this.dbPlatform = dbPlatform;
this.binder = binder;
this.draftSupport = draftSupport;
@@ -102,7 +97,7 @@ class CQueryBuilder {
SpiQuery query = request.getQuery();
String rootTableAlias = query.getAlias();
- query.setDelete();
+ query.setupForDeleteOrUpdate(deleteRequest);
CQueryPredicates predicates = new CQueryPredicates(binder, request);
CQueryPlan queryPlan = request.getQueryPlan();
@@ -135,16 +130,16 @@ class CQueryBuilder {
if (sqlTree.noJoins()) {
if (dbPlatform.isSupportsDeleteTableAlias()) {
// delete from table ...
- return aliasReplace(buildSql("delete", request, predicates, sqlTree).getSql(), alias);
+ return aliasReplace(buildSqlDelete("delete", request, predicates, sqlTree).getSql(), alias);
} else if (isMySql(dbPlatform.getPlatform())) {
- return aliasReplace(buildSql("delete " + alias, request, predicates, sqlTree).getSql(), alias);
+ return aliasReplace(buildSqlDelete("delete " + alias, request, predicates, sqlTree).getSql(), alias);
} else {
// simple - delete from table ...
- return aliasStrip(buildSql("delete", request, predicates, sqlTree).getSql());
+ return aliasStrip(buildSqlDelete("delete", request, predicates, sqlTree).getSql());
}
}
// wrap as - delete from table where id in (select id ...)
- String sql = buildSql(null, request, predicates, sqlTree).getSql();
+ String sql = buildSqlDelete(null, request, predicates, sqlTree).getSql();
sql = request.getBeanDescriptor().getDeleteByIdInSql() + "in (" + sql + ")";
sql = aliasReplace(sql, alias);
return sql;
@@ -168,7 +163,7 @@ class CQueryBuilder {
sb.append(" set ").append(predicates.getDbUpdateClause());
String updateClause = sb.toString();
- if (sqlTree.noJoins()) {
+ if (sqlTree.noJoins() && request.isInlineSqlUpdateLimit()) {
// simple - update table set ... where ...
return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql());
}
@@ -547,137 +542,156 @@ class CQueryBuilder {
* Return the SQL response with row limiting (when not an update statement).
*/
private SqlLimitResponse buildSql(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select) {
- return buildSql(selectClause, request, predicates, select, false);
- }
-
- /**
- * Return the SQL response for update statement (stripping table alias for find by id expression).
- */
- private SqlLimitResponse buildSqlUpdate(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select) {
- return buildSql(selectClause, request, predicates, select, true);
- }
-
- private SqlLimitResponse buildSql(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select, boolean stripAlias) {
-
SpiQuery> query = request.getQuery();
-
if (query.isNativeSql()) {
return new SqlLimitResponse(query.getGeneratedSql(), false);
}
if (query.isRawSql()) {
return rawSqlHandler.buildSql(request, predicates, query.getRawSql().getSql());
}
+ return new BuildReq(selectClause, request, predicates, select).buildSql();
+ }
- boolean distinct = query.isDistinct() || select.isSqlDistinct();
- boolean useSqlLimiter = false;
- StringBuilder sb = new StringBuilder(500);
- String dbOrderBy = predicates.getDbOrderBy();
+ private SqlLimitResponse buildSqlDelete(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select) {
+ return new BuildReq(selectClause, request, predicates, select).buildSql();
+ }
- if (selectClause != null) {
- sb.append(selectClause);
+ private SqlLimitResponse buildSqlUpdate(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select) {
+ return new BuildReq(selectClause, request, predicates, select, true).buildSql();
+ }
- } else {
- useSqlLimiter = (query.hasMaxRowsOrFirstRow() && select.getManyProperty() == null);
+ private class BuildReq {
+ private final StringBuilder sb = new StringBuilder(500);
+ private final String selectClause;
+ private final OrmQueryRequest> request;
+ private final SpiQuery> query;
+ private final CQueryPredicates predicates;
+ private final SqlTree select;
+ private final boolean updateStatement;
- if (!useSqlLimiter) {
- sb.append("select ");
- if (distinct) {
- if (request.isInlineCountDistinct()) {
- sb.append("count(");
- }
- sb.append("distinct ");
- String distinctOn = select.getDistinctOn();
- if (distinctOn != null) {
- sb.append("on (");
- sb.append(distinctOn).append(") ");
+ private final boolean distinct;
+ private final String dbOrderBy;
+ private boolean useSqlLimiter;
+ private boolean hasWhere;
+
+ private BuildReq(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select) {
+ this(selectClause, request, predicates, select, false);
+ }
+
+ private BuildReq(String selectClause, OrmQueryRequest> request, CQueryPredicates predicates, SqlTree select, boolean updateStatement) {
+ this.selectClause = selectClause;
+ this.request = request;
+ this.query = request.getQuery();
+ this.predicates = predicates;
+ this.select = select;
+ this.updateStatement = updateStatement;
+ this.distinct = query.isDistinct() || select.isSqlDistinct();
+ this.dbOrderBy = predicates.getDbOrderBy();
+ }
+
+ private void appendSelect() {
+ if (selectClause != null) {
+ sb.append(selectClause);
+
+ } else {
+ useSqlLimiter = (query.hasMaxRowsOrFirstRow() && select.getManyProperty() == null);
+ if (!useSqlLimiter) {
+ appendSelectDistinct();
+ }
+ if (query.isCountDistinct() && query.isSingleAttribute()) {
+ sb.append("r1.attribute_, count(*) from (select ").append(select.getSelectSql()).append(" as attribute_");
+ } else {
+ sb.append(select.getSelectSql());
+ }
+ if (request.isInlineCountDistinct()) {
+ sb.append(")");
+ }
+ if (distinct && dbOrderBy != null && !query.isSingleAttribute()) {
+ // add the orderBy columns to the select clause (due to distinct)
+ final OrderBy> orderBy = query.getOrderBy();
+ if (orderBy != null && orderBy.supportsSelect()) {
+ sb.append(", ").append(DbOrderByTrim.trim(dbOrderBy));
}
}
}
- if (query.isCountDistinct() && query.isSingleAttribute()) {
- sb.append("r1.attribute_, count(*) from (select ");
- sb.append(select.getSelectSql());
- sb.append(" as attribute_");
- } else {
- sb.append(select.getSelectSql());
- }
- if (request.isInlineCountDistinct()) {
- sb.append(")");
- }
- if (distinct && dbOrderBy != null && !query.isSingleAttribute()) {
- // add the orderBy columns to the select clause (due to distinct)
- final OrderBy> orderBy = query.getOrderBy();
- if (orderBy != null && orderBy.supportsSelect()) {
- sb.append(", ").append(DbOrderByTrim.trim(dbOrderBy));
+ }
+
+ private void appendSelectDistinct() {
+ sb.append("select ");
+ if (distinct) {
+ if (request.isInlineCountDistinct()) {
+ sb.append("count(");
+ }
+ sb.append("distinct ");
+ String distinctOn = select.getDistinctOn();
+ if (distinctOn != null) {
+ sb.append("on (").append(distinctOn).append(") ");
}
}
}
- if (selectClause == null || !selectClause.startsWith("update")) {
- sb.append(" from ");
- sb.append(select.getFromSql());
- }
-
- String inheritanceWhere = select.getInheritanceWhereSql();
-
- boolean hasWhere = false;
- if (!inheritanceWhere.isEmpty()) {
- sb.append(" where");
- sb.append(inheritanceWhere);
- hasWhere = true;
- }
-
- if (query.isAsOfBaseTable() && !historySupport.isStandardsBased()) {
- hasWhere = appendWhere(hasWhere, sb);
- sb.append(historySupport.getAsOfPredicate(request.getBaseTableAlias()));
- }
-
- if (request.isFindById() || query.getId() != null) {
- appendWhere(hasWhere, sb);
-
- BeanDescriptor> desc = request.getBeanDescriptor();
- String idSql = desc.getIdBinderIdSql(query.getAlias());
- if (idSql.isEmpty()) {
- throw new IllegalStateException("Executing FindById query on entity bean " + desc.getName()
- + " that doesn't have an @Id property??");
+ private void appendFrom() {
+ if (selectClause == null || !selectClause.startsWith("update")) {
+ sb.append(" from ");
+ sb.append(select.getFromSql());
}
- if (stripAlias) {
- // strip the table alias for use in update statement
- idSql = StringHelper.replaceString(idSql, "t0.", "");
- }
- sb.append(idSql).append(" ");
- hasWhere = true;
}
- String dbWhere = predicates.getDbWhere();
- if (hasValue(dbWhere)) {
- if (!hasWhere) {
- hasWhere = true;
- sb.append(" where ");
- } else {
+ private void appendAndOrWhere() {
+ if (hasWhere) {
sb.append(" and ");
- }
- sb.append(dbWhere);
- }
-
- String dbFilterMany = predicates.getDbFilterMany();
- if (hasValue(dbFilterMany)) {
- if (!hasWhere) {
- hasWhere = true;
- sb.append(" where ");
} else {
- sb.append("and ");
+ sb.append(" where ");
+ hasWhere = true;
}
- sb.append(dbFilterMany);
}
- if (!query.isIncludeSoftDeletes()) {
+ private void appendInheritanceWhere() {
+ String inheritanceWhere = select.getInheritanceWhereSql();
+ if (!inheritanceWhere.isEmpty()) {
+ sb.append(" where");
+ sb.append(inheritanceWhere);
+ hasWhere = true;
+ }
+ }
+
+ private void appendHistoryAsOfPredicate() {
+ if (query.isAsOfBaseTable() && !historySupport.isStandardsBased()) {
+ appendAndOrWhere();
+ sb.append(historySupport.getAsOfPredicate(request.getBaseTableAlias()));
+ }
+ }
+
+ private void appendFindId() {
+ if (request.isFindById() || query.getId() != null) {
+ appendAndOrWhere();
+
+ BeanDescriptor> desc = request.getBeanDescriptor();
+ String idSql = desc.getIdBinderIdSql(query.getAlias());
+ if (idSql.isEmpty()) {
+ throw new IllegalStateException("Executing FindById query on entity bean " + desc.getName()
+ + " that doesn't have an @Id property??");
+ }
+ if (updateStatement) {
+ // strip the table alias for use in update statement
+ idSql = StringHelper.replaceString(idSql, "t0.", "");
+ }
+ sb.append(idSql).append(" ");
+ hasWhere = true;
+ }
+ }
+
+ private void appendToWhere(String predicate) {
+ if (hasValue(predicate)) {
+ appendAndOrWhere();
+ sb.append(predicate);
+ }
+ }
+
+ private void appendSoftDelete() {
List softDeletePredicates = query.getSoftDeletePredicates();
if (softDeletePredicates != null) {
- if (!hasWhere) {
- sb.append(" where ");
- } else {
- sb.append(" and ");
- }
+ appendAndOrWhere();
for (int i = 0; i < softDeletePredicates.size(); i++) {
if (i > 0) {
sb.append(" and ");
@@ -687,69 +701,75 @@ class CQueryBuilder {
}
}
- String groupBy = select.getGroupBy();
- if (groupBy != null) {
- sb.append(" group by ").append(groupBy);
+ private SqlLimitResponse buildSql() {
+ appendSelect();
+ appendFrom();
+ appendInheritanceWhere();
+ appendHistoryAsOfPredicate();
+ appendFindId();
+ appendToWhere(predicates.getDbWhere());
+ appendToWhere(predicates.getDbFilterMany());
+ if (!query.isIncludeSoftDeletes()) {
+ appendSoftDelete();
+ }
+
+ String groupBy = select.getGroupBy();
+ if (groupBy != null) {
+ sb.append(" group by ").append(groupBy);
+ }
+
+ String dbHaving = predicates.getDbHaving();
+ if (hasValue(dbHaving)) {
+ sb.append(" having ").append(dbHaving);
+ }
+
+ if (dbOrderBy != null && !query.isCountDistinct()) {
+ sb.append(" order by ").append(dbOrderBy);
+ }
+
+ if (query.isCountDistinct() && query.isSingleAttribute()) {
+ sb.append(") r1 group by r1.attribute_");
+ sb.append(toSql(query.getCountDistinctOrder()));
+ }
+
+ if (useSqlLimiter) {
+ // use LIMIT/OFFSET, ROW_NUMBER() or rownum type SQL query limitation
+ SqlLimitRequest r = new OrmQueryLimitRequest(sb.toString(), dbOrderBy, query, dbPlatform, distinct);
+ return sqlLimiter.limit(r);
+ } else {
+ if (updateStatement) {
+ final int maxRows = query.getMaxRows();
+ if (maxRows > 0) {
+ // limit on update statement only support on platforms with supportsMaxRowsOnUpdate
+ sb.append(" limit ").append(maxRows);
+ }
+ }
+ return new SqlLimitResponse(dbPlatform.completeSql(sb.toString(), query), false);
+ }
}
- String dbHaving = predicates.getDbHaving();
- if (hasValue(dbHaving)) {
- sb.append(" having ").append(dbHaving);
+ private String toSql(CountDistinctOrder orderBy) {
+ switch (orderBy) {
+ case ATTR_ASC:
+ return " order by r1.attribute_";
+ case ATTR_DESC:
+ return " order by r1.attribute_ desc";
+ case COUNT_ASC_ATTR_ASC:
+ return " order by count(*), r1.attribute_";
+ case COUNT_ASC_ATTR_DESC:
+ return " order by count(*), r1.attribute_ desc";
+ case COUNT_DESC_ATTR_ASC:
+ return " order by count(*) desc, r1.attribute_";
+ case COUNT_DESC_ATTR_DESC:
+ return " order by count(*) desc, r1.attribute_ desc";
+ default:
+ throw new IllegalArgumentException("Illegal enum: " + orderBy);
+ }
}
- if (dbOrderBy != null && !query.isCountDistinct()) {
- sb.append(" order by ").append(dbOrderBy);
+ private boolean hasValue(String s) {
+ return s != null && !s.isEmpty();
}
-
- if (query.isCountDistinct() && query.isSingleAttribute()) {
- sb.append(") r1 group by r1.attribute_");
- sb.append(toSql(query.getCountDistinctOrder()));
- }
-
- if (useSqlLimiter) {
- // use LIMIT/OFFSET, ROW_NUMBER() or rownum type SQL query limitation
- SqlLimitRequest r = new OrmQueryLimitRequest(sb.toString(), dbOrderBy, query, dbPlatform, distinct);
- return sqlLimiter.limit(r);
-
- } else {
- return new SqlLimitResponse(dbPlatform.completeSql(sb.toString(), query), false);
- }
-
- }
-
- private String toSql(CountDistinctOrder orderBy) {
- switch (orderBy) {
- case ATTR_ASC:
- return " order by r1.attribute_";
- case ATTR_DESC:
- return " order by r1.attribute_ desc";
- case COUNT_ASC_ATTR_ASC:
- return " order by count(*), r1.attribute_";
- case COUNT_ASC_ATTR_DESC:
- return " order by count(*), r1.attribute_ desc";
- case COUNT_DESC_ATTR_ASC:
- return " order by count(*) desc, r1.attribute_";
- case COUNT_DESC_ATTR_DESC:
- return " order by count(*) desc, r1.attribute_ desc";
- default:
- throw new IllegalArgumentException("Illegal enum: " + orderBy);
- }
- }
-
- /**
- * Append where or and based on the hasWhere flag.
- */
- private boolean appendWhere(boolean hasWhere, StringBuilder sb) {
- if (hasWhere) {
- sb.append(" and ");
- } else {
- sb.append(" where ");
- }
- return true;
- }
-
- private boolean hasValue(String s) {
- return s != null && !s.isEmpty();
}
boolean isPlatformDistinctOn() {
@@ -759,7 +779,7 @@ class CQueryBuilder {
/**
* Return the 'for update' FROM hint (sql server).
*/
- public String fromForUpdate(SpiQuery> query) {
+ String fromForUpdate(SpiQuery> query) {
Query.ForUpdate mode = query.getForUpdateMode();
if (mode == null) {
return null;
diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
index 61bd4513f..ab0824901 100644
--- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
+++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
@@ -692,13 +692,15 @@ public class DefaultOrmQuery implements SpiQuery {
}
/**
- * Setup to be a delete query.
+ * Setup to be a delete or update query.
*/
@Override
- public void setDelete() {
+ public void setupForDeleteOrUpdate(boolean deleteRequest) {
// unset any paging and select on the id in the case where the query
// includes joins and we use - delete ... where id in (...)
- maxRows = 0;
+ if (deleteRequest) {
+ maxRows = 0;
+ }
firstRow = 0;
forUpdate = null;
rootTableAlias = "${RTA}"; // alias we remove later
diff --git a/src/test/java/io/ebean/UpdateQueryTest.java b/src/test/java/io/ebean/UpdateQueryTest.java
index cfbdb02f6..7e945a2d5 100644
--- a/src/test/java/io/ebean/UpdateQueryTest.java
+++ b/src/test/java/io/ebean/UpdateQueryTest.java
@@ -1,5 +1,6 @@
package io.ebean;
+import io.ebean.annotation.ForPlatform;
import io.ebean.annotation.IgnorePlatform;
import io.ebean.annotation.Platform;
import io.ebean.meta.MetaOrmQueryMetric;
@@ -16,7 +17,6 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
-
public class UpdateQueryTest extends BaseTestCase {
@Test
@@ -143,12 +143,10 @@ public class UpdateQueryTest extends BaseTestCase {
assertThat(query.getGeneratedSql()).contains("update o_customer cust set status=?, updtime=? where id > ?");
}
+ @IgnorePlatform(Platform.MYSQL)
@Test
public void withJoin() {
- if (isMySql()) {
- return;
- }
EbeanServer server = server();
Country nz = server.getReference(Country.class, "NZ");
@@ -169,6 +167,51 @@ public class UpdateQueryTest extends BaseTestCase {
assertThat(sqlOf(query)).contains("update o_customer set status=?, updtime=? where id in (select t0.id from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id where t0.status = ? and t1.country_code = ? and t0.id > ?)");
}
+ @ForPlatform({Platform.H2, Platform.POSTGRES})
+ @Test
+ public void withJoinAndLimit() {
+
+ EbeanServer server = server();
+
+ Country nz = server.getReference(Country.class, "NZ");
+
+ LoggedSqlCollector.start();
+
+ server.update(Customer.class)
+ .set("status", Customer.Status.ACTIVE)
+ .where()
+ .eq("billingAddress.country", nz)
+ .gt("id", 1000)
+ .setMaxRows(100)
+ .update();
+
+ final List sql = LoggedSqlCollector.stop();
+ assertThat(sql.get(0)).contains("update o_customer set status=? where id in (select t0.id from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id where t1.country_code = ? and t0.id > ? limit 100)");
+ }
+
+ @ForPlatform({Platform.H2, Platform.POSTGRES, Platform.MYSQL})
+ @Test
+ public void simpleWithLimit() {
+
+ EbeanServer server = server();
+
+ LoggedSqlCollector.start();
+
+ server.update(Customer.class)
+ .set("status", Customer.Status.ACTIVE)
+ .where()
+ .gt("id", 1000)
+ .setMaxRows(100)
+ .update();
+
+ final List sql = LoggedSqlCollector.stop();
+ if (isMySql() || isH2()) {
+ assertThat(sql.get(0)).contains("update o_customer set status=? where id > ? limit 100");
+ } else {
+ assertThat(sql.get(0)).contains("update o_customer set status=? where id in (select t0.id from o_customer t0 where t0.id > ? limit 100)");
+ }
+ }
+
@Test
public void whereIsEmpty() {
diff --git a/src/test/java/org/tests/basic/TestCreateEntityBean.java b/src/test/java/org/tests/basic/TestCreateEntityBean.java
index 6f544db53..af15e5380 100644
--- a/src/test/java/org/tests/basic/TestCreateEntityBean.java
+++ b/src/test/java/org/tests/basic/TestCreateEntityBean.java
@@ -3,6 +3,8 @@ package org.tests.basic;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.Ebean;
+import io.ebean.annotation.IgnorePlatform;
+import io.ebean.annotation.Platform;
import org.junit.Test;
import org.tests.model.basic.EDefaultProp;
@@ -11,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
public class TestCreateEntityBean extends BaseTestCase {
+ @IgnorePlatform(Platform.SQLSERVER)
@Test
public void testDefaultRelation() {
diff --git a/src/test/java/org/tests/query/TestQueryFilterMany.java b/src/test/java/org/tests/query/TestQueryFilterMany.java
index 2dff48308..fcc734a98 100644
--- a/src/test/java/org/tests/query/TestQueryFilterMany.java
+++ b/src/test/java/org/tests/query/TestQueryFilterMany.java
@@ -193,6 +193,6 @@ public class TestQueryFilterMany extends BaseTestCase {
assertThat(sql).hasSize(2);
assertThat(sql.get(0)).contains(" from o_customer t0");
assertThat(sql.get(1)).contains("from contact t0 where ");
- assertThat(sql.get(1)).contains("and (t0.first_name is not null and lower(t0.email) like ? escape'|' )");
+ assertThat(sql.get(1)).contains("and (t0.first_name is not null and lower(t0.email) like ?");
}
}