#583 - MSSQL Server - Delete query syntax error, mssql does not like the table alias in the delete statement

This commit is contained in:
Robin Bygrave
2016-03-15 01:03:08 +13:00
parent 5216014d50
commit db9d39ef61
3 changed files with 45 additions and 18 deletions
@@ -10,6 +10,7 @@ import com.avaje.ebean.config.dbplatform.SqlLimitResponse;
import com.avaje.ebean.config.dbplatform.SqlLimiter;
import com.avaje.ebean.event.readaudit.ReadAuditQueryPlan;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebean.util.StringHelper;
import com.avaje.ebeaninternal.api.ManyWhereJoins;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
@@ -92,6 +93,7 @@ public class CQueryBuilder {
public <T> CQueryDelete buildDeleteQuery(OrmQueryRequest<T> request) {
SpiQuery<T> query = request.getQuery();
String rootTableAlias = query.getAlias();
query.setDelete();
CQueryPredicates predicates = new CQueryPredicates(binder, request);
@@ -112,12 +114,13 @@ public class CQueryBuilder {
String sql;
if (!includeJoins) {
// simple - delete from table ...
sql = buildSql("delete", request, predicates, sqlTree).getSql();
sql = aliasStrip(buildSql("delete", request, predicates, sqlTree).getSql());
} else {
// wrap as - delete from table where id in (select id ...)
sql = buildSql(null, request, predicates, sqlTree).getSql();
sql = request.getBeanDescriptor().getDeleteByIdInSql() + "in (" + sql + ")";
String alias = (rootTableAlias == null) ? "t0" : rootTableAlias;
sql = aliasReplace(sql, alias);
}
// cache the query plan
@@ -127,6 +130,22 @@ public class CQueryBuilder {
return new CQueryDelete(request, predicates, sql);
}
/**
* Strip the root table alias.
*/
private String aliasStrip(String sql) {
sql = StringHelper.replaceString(sql, "${RTA}.", "");
return StringHelper.replaceString(sql, " ${RTA}", "");
}
/**
* Replace the root table alias.
*/
private String aliasReplace(String sql, String replaceWith) {
sql = StringHelper.replaceString(sql, "${RTA}.", replaceWith+".");
return StringHelper.replaceString(sql, "${RTA}", replaceWith);
}
/**
* Build the row count query.
*/
@@ -528,6 +528,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
maxRows = 0;
firstRow = 0;
forUpdate = false;
rootTableAlias = "${RTA}"; // alias we remove later
setSelectId();
}
@@ -41,7 +41,7 @@ public class TestDeleteByQuery extends BaseTestCase {
loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("delete from contact t0 where t0.first_name =");
assertThat(loggedSql.get(0)).contains("delete from contact where first_name =");
server.find(Contact.class).select("id").where().eq("firstName", "NotARealFirstName").delete();
@@ -54,27 +54,35 @@ public class TestDeleteByQuery extends BaseTestCase {
@Test
public void testWithForUpdate() {
EbeanServer server = Ebean.getDefaultServer();
if (server.getName().equals("mysql")) {
// MySql does not the sub query selecting from the delete table
return;
}
LoggedSqlCollector.start();
server.find(Customer.class)
.where().eq("name","FatsDomino")
Ebean.find(Customer.class)
.where().eq("name","Don Roberto")
.query().setForUpdate(true)
.delete();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertThat(sql.get(0)).contains("delete from o_customer where name = ?");
}
@Test
public void delete_queryString() {
LoggedSqlCollector.start();
Ebean.createQuery(Customer.class, "where name = :name")
.setParameter("name","Don Roberto")
.delete();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertThat(sql.get(0)).contains("delete from o_customer where name = ?");
}
@Test
public void testCommit() {
EbeanServer server = Ebean.getDefaultServer();
if (server.getName().equals("mysql")) {
// MySql does not the sub query selecting from the delete table
return;
}
ResetBasicData.reset();
List<Customer> all = Customer.find.all();
@@ -85,10 +93,9 @@ public class TestDeleteByQuery extends BaseTestCase {
Ebean.save(contact);
Ebean.find(Contact.class).select("id").where().eq("firstName", "DelByQueryFirstName").delete();
Ebean.find(Contact.class).where().eq("firstName", "DelByQueryFirstName").delete();
Contact contactFind = Ebean.find(Contact.class, contact.getId());
assertThat(contactFind).isNull();
}
}