#1953 - Do we need SqlServer2005Platform and SqlServer2005SqlLimiter?

This commit is contained in:
rob bygrave
2020-02-22 11:48:16 +13:00
parent 3878b02cff
commit 0891c067d5
18 changed files with 37 additions and 180 deletions
@@ -40,8 +40,7 @@ public class LimitOffsetSqlLimiter implements SqlLimiter {
}
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
@@ -7,14 +7,11 @@ public class SqlLimitResponse {
final String sql;
final boolean includesRowNumberColumn;
/**
* Create the response.
*/
public SqlLimitResponse(String sql, boolean includesRowNumberColumn) {
public SqlLimitResponse(String sql) {
this.sql = sql;
this.includesRowNumberColumn = includesRowNumberColumn;
}
/**
@@ -24,11 +21,4 @@ public class SqlLimitResponse {
return sql;
}
/**
* Returns true if a ROW_NUMBER column is used in the query.
*/
public boolean isIncludesRowNumberColumn() {
return includesRowNumberColumn;
}
}
@@ -22,6 +22,6 @@ public class Db2SqlLimiter implements SqlLimiter {
}
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
@@ -29,7 +29,6 @@ public class HanaSqlLimiter implements SqlLimiter {
}
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
}
@@ -28,7 +28,7 @@ class OracleAnsiSqlRowsLimiter implements SqlLimiter {
if (maxRows > 0) {
sb.append(" fetch next ").append(maxRows).append(" rows only");
}
return new SqlLimitResponse(sb.toString(), false);
return new SqlLimitResponse(sb.toString());
}
}
@@ -48,7 +48,7 @@ class OracleRownumSqlLimiter implements SqlLimiter {
}
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
@@ -35,8 +35,7 @@ public class SqlAnywhereLimiter implements SqlLimiter {
sb.append(dbSql);
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
@@ -1,11 +0,0 @@
package io.ebean.config.dbplatform.sqlserver;
/**
* SQL Server platform using the older ROW_NUMBER() mechanism.
*/
public class SqlServer2005Platform extends SqlServer16Platform {
public SqlServer2005Platform() {
this.sqlLimiter = new SqlServer2005SqlLimiter();
}
}
@@ -1,79 +0,0 @@
package io.ebean.config.dbplatform.sqlserver;
import io.ebean.config.dbplatform.SqlLimitRequest;
import io.ebean.config.dbplatform.SqlLimitResponse;
import io.ebean.config.dbplatform.SqlLimiter;
/**
* Use top and row_number() function to limit sql results.
*/
public class SqlServer2005SqlLimiter implements SqlLimiter {
final String rowNumberWindowAlias;
/**
* Specify the name of the rowNumberWindowAlias.
*/
public SqlServer2005SqlLimiter(String rowNumberWindowAlias) {
this.rowNumberWindowAlias = rowNumberWindowAlias;
}
public SqlServer2005SqlLimiter() {
this("as limitresult");
}
@Override
public SqlLimitResponse limit(SqlLimitRequest request) {
StringBuilder sb = new StringBuilder(500);
int firstRow = request.getFirstRow();
int lastRow = request.getMaxRows();
if (lastRow > 0) {
lastRow += firstRow;
}
if (firstRow < 1) {
// just use top n
sb.append("select ");
if (request.isDistinct()) {
sb.append("distinct ");
}
sb.append("top ").append(lastRow).append(" ");
sb.append(request.getDbSql());
return new SqlLimitResponse(sb.toString(), false);
}
/*
* SELECT * FROM (SELECT TOP 20 ROW_NUMBER() OVER (ORDER BY ...) AS rn, ...)
* AS limitresult WHERE rn >= 11 AND rn <= 20
*/
sb.append("select * ").append(NEW_LINE).append("from ( ");
sb.append("select ");
if (request.isDistinct()) {
sb.append("distinct ");
}
sb.append("top ").append(lastRow);
sb.append(" row_number() over (order by ");
sb.append(request.getDbOrderBy());
sb.append(") as rn, ");
sb.append(request.getDbSql());
sb.append(NEW_LINE).append(") ");
sb.append(rowNumberWindowAlias);
sb.append(" where ");
sb.append(" rn > ").append(firstRow);
if (lastRow > 0) {
sb.append(" and ");
sb.append(" rn <= ").append(lastRow);
}
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
return new SqlLimitResponse(sql, true);
}
}
@@ -29,7 +29,7 @@ public class SqlServerSqlLimiter implements SqlLimiter {
}
sb.append("top ").append(maxRows).append(" ");
sb.append(dbSql);
return new SqlLimitResponse(sb.toString(), false);
return new SqlLimitResponse(sb.toString());
}
sb.append("select ");
@@ -43,8 +43,7 @@ public class SqlServerSqlLimiter implements SqlLimiter {
if (maxRows > 0) {
sb.append(" fetch next ").append(maxRows).append(" rows only");
}
String sql = sb.toString();
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sb.toString());
}
}
@@ -135,11 +135,6 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
*/
private final String logWhereSql;
/**
* Set to true if the row number column is included in the sql.
*/
private final boolean rowNumberIncluded;
/**
* Tree that knows how to build the master and detail beans from the
* resultSet.
@@ -225,7 +220,6 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
this.manyProperty = sqlTree.getManyProperty();
this.sql = queryPlan.getSql();
this.rawSql = queryPlan.isRawSql();
this.rowNumberIncluded = queryPlan.isRowNumberIncluded();
this.logWhereSql = queryPlan.getLogWhereSql();
this.desc = request.getBeanDescriptor();
this.predicates = predicates;
@@ -504,10 +498,6 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
rowCount++;
dataReader.resetColumnPosition();
if (rowNumberIncluded) {
// row_number() column used for limit features
dataReader.incrementPos(1);
}
return true;
}
@@ -117,7 +117,7 @@ class CQueryBuilder {
}
// cache the query plan
queryPlan = new CQueryPlan(request, sql, sqlTree, false, predicates.getLogWhereSql());
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
request.putQueryPlan(queryPlan);
return new CQueryUpdate(request, predicates, queryPlan);
}
@@ -206,7 +206,7 @@ class CQueryBuilder {
SqlTree sqlTree = createSqlTree(request, predicates);
SqlLimitResponse s = buildSql(null, request, predicates, sqlTree);
queryPlan = new CQueryPlan(request, s.getSql(), sqlTree, s.isIncludesRowNumberColumn(), predicates.getLogWhereSql());
queryPlan = new CQueryPlan(request, s.getSql(), sqlTree, predicates.getLogWhereSql());
request.putQueryPlan(queryPlan);
return new CQueryFetchSingleAttribute(request, predicates, queryPlan, query.isCountDistinct());
}
@@ -305,7 +305,7 @@ class CQueryBuilder {
}
// cache the query plan
queryPlan = new CQueryPlan(request, sql, sqlTree, s.isIncludesRowNumberColumn(), predicates.getLogWhereSql());
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
request.putQueryPlan(queryPlan);
return new CQueryRowCount(queryPlan, request, predicates);
@@ -550,7 +550,7 @@ class CQueryBuilder {
private SqlLimitResponse buildSql(String selectClause, OrmQueryRequest<?> request, CQueryPredicates predicates, SqlTree select) {
SpiQuery<?> query = request.getQuery();
if (query.isNativeSql()) {
return new SqlLimitResponse(query.getGeneratedSql(), false);
return new SqlLimitResponse(query.getGeneratedSql());
}
if (query.isRawSql()) {
return rawSqlHandler.buildSql(request, predicates, query.getRawSql().getSql());
@@ -750,7 +750,7 @@ class CQueryBuilder {
sb.append(" limit ").append(maxRows);
}
}
return new SqlLimitResponse(dbPlatform.completeSql(sb.toString(), query), false);
return new SqlLimitResponse(dbPlatform.completeSql(sb.toString(), query));
}
}
@@ -28,7 +28,7 @@ class CQueryBuilderRawSql {
if (rsql == null) {
// this is a ResultSet based RawSql query - just use some placeholder for the SQL
return new SqlLimitResponse(CQueryPlan.RESULT_SET_BASED_RAW_SQL, false);
return new SqlLimitResponse(CQueryPlan.RESULT_SET_BASED_RAW_SQL);
}
if (!rsql.isParsed()) {
@@ -38,8 +38,7 @@ class CQueryBuilderRawSql {
// convert named parameters into positioned parameters
sql = BindParamsParser.parse(bindParams, sql);
}
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
String orderBy = getOrderBy(predicates, rsql);
@@ -56,7 +55,7 @@ class CQueryBuilderRawSql {
// add back select keyword (it was removed to support sqlQueryLimiter)
String prefix = "select " + (rsql.isDistinct() ? "distinct " : "");
sql = prefix + sql;
return new SqlLimitResponse(sql, false);
return new SqlLimitResponse(sql);
}
}
@@ -66,8 +66,6 @@ public class CQueryPlan implements SpiQueryPlan {
private final boolean rawSql;
private final boolean rowNumberIncluded;
private final String sql;
private final String hash;
@@ -112,7 +110,6 @@ public class CQueryPlan implements SpiQueryPlan {
this.location = location();
this.asOfTableCount = query.getAsOfTableCount();
this.sql = sqlRes.getSql();
this.rowNumberIncluded = sqlRes.isIncludesRowNumberColumn();
this.sqlTree = sqlTree;
this.rawSql = rawSql;
this.logWhereSql = logWhereSql;
@@ -126,7 +123,7 @@ public class CQueryPlan implements SpiQueryPlan {
/**
* Create a query plan for a raw sql query.
*/
CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTree sqlTree, boolean rowNumberIncluded, String logWhereSql) {
CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTree sqlTree, String logWhereSql) {
this.server = request.getServer();
this.dataTimeZone = server.getDataTimeZone();
this.beanType = request.getBeanDescriptor().getBeanType();
@@ -135,12 +132,11 @@ public class CQueryPlan implements SpiQueryPlan {
this.label = query.getPlanLabel();
this.name = deriveName(label, query.getType());
this.location = location();
this.planKey = buildPlanKey(sql, rowNumberIncluded, logWhereSql);
this.planKey = buildPlanKey(sql, logWhereSql);
this.asOfTableCount = 0;
this.sql = sql;
this.sqlTree = sqlTree;
this.rawSql = false;
this.rowNumberIncluded = rowNumberIncluded;
this.logWhereSql = logWhereSql;
this.encryptedProps = sqlTree.getEncryptedProps();
this.stats = new CQueryPlanStats(this);
@@ -171,8 +167,8 @@ public class CQueryPlan implements SpiQueryPlan {
return (profileLocation == null) ? null : profileLocation.location();
}
private CQueryPlanKey buildPlanKey(String sql, boolean rowNumberIncluded, String logWhereSql) {
return new RawSqlQueryPlanKey(sql, false, rowNumberIncluded, logWhereSql);
private CQueryPlanKey buildPlanKey(String sql, String logWhereSql) {
return new RawSqlQueryPlanKey(sql, false, logWhereSql);
}
@Override
@@ -297,10 +293,6 @@ public class CQueryPlan implements SpiQueryPlan {
return rawSql;
}
boolean isRowNumberIncluded() {
return rowNumberIncluded;
}
String getLogWhereSql() {
return logWhereSql;
}
@@ -23,7 +23,7 @@ class CQueryPlanRawSql extends CQueryPlan {
@Override
public DataReader createDataReader(ResultSet rset) {
return new RsetDataReaderIndexed(dataTimeZone, rset, rsetIndexPositions, isRowNumberIncluded());
return new RsetDataReaderIndexed(dataTimeZone, rset, rsetIndexPositions);
}
private int[] createIndexPositions(OrmQueryRequest<?> request, SqlTree sqlTree) {
@@ -11,13 +11,11 @@ class RawSqlQueryPlanKey implements CQueryPlanKey {
private final String sql;
private final boolean rawSql;
private final boolean rowNumberIncluded;
private final String logWhereSql;
RawSqlQueryPlanKey(String sql, boolean rawSql, boolean rowNumberIncluded, String logWhereSql) {
RawSqlQueryPlanKey(String sql, boolean rawSql, String logWhereSql) {
this.sql = sql;
this.rawSql = rawSql;
this.rowNumberIncluded = rowNumberIncluded;
this.logWhereSql = logWhereSql;
}
@@ -49,7 +47,6 @@ class RawSqlQueryPlanKey implements CQueryPlanKey {
RawSqlQueryPlanKey that = (RawSqlQueryPlanKey) o;
if (rawSql != that.rawSql) return false;
if (rowNumberIncluded != that.rowNumberIncluded) return false;
if (!sql.equals(that.sql)) return false;
return Objects.equals(logWhereSql, that.logWhereSql);
}
@@ -58,7 +55,6 @@ class RawSqlQueryPlanKey implements CQueryPlanKey {
public int hashCode() {
int result = sql.hashCode();
result = 92821 * result + (rawSql ? 1 : 0);
result = 92821 * result + (rowNumberIncluded ? 1 : 0);
result = 92821 * result + logWhereSql.hashCode();
return result;
}
@@ -11,17 +11,9 @@ public class RsetDataReaderIndexed extends RsetDataReader {
private final int[] rsetIndexPositions;
public RsetDataReaderIndexed(DataTimeZone dataTimeZone, ResultSet rset, int[] rsetIndexPositions, boolean rowNumberIncluded) {
public RsetDataReaderIndexed(DataTimeZone dataTimeZone, ResultSet rset, int[] rsetIndexPositions) {
super(dataTimeZone, rset);
if (!rowNumberIncluded) {
this.rsetIndexPositions = rsetIndexPositions;
} else {
this.rsetIndexPositions = new int[rsetIndexPositions.length + 1];
for (int i = 0; i < rsetIndexPositions.length; i++) {
// increment all the column indexes by 1
this.rsetIndexPositions[i + 1] = rsetIndexPositions[i] + 1;
}
}
this.rsetIndexPositions = rsetIndexPositions;
}
@Override
@@ -10,7 +10,7 @@ public class RawSqlQueryPlanKeyTest {
@Test
public void test_equals_same_instance() {
RawSqlQueryPlanKey key = key("select foo", true, true, "");
RawSqlQueryPlanKey key = key("select foo", true, "");
assertThat(key).isEqualTo(key);
assertThat(key.hashCode()).isEqualTo(key.hashCode());
}
@@ -18,41 +18,33 @@ public class RawSqlQueryPlanKeyTest {
@Test
public void test_equals_diff_instance() {
assertThat(key("select foo", true, true, "")).isEqualTo(key("select foo", true, true, ""));
assertThat(key("select foo", true, true, "").hashCode()).isEqualTo(key("select foo", true, true, "").hashCode());
assertThat(key("select foo", true, "")).isEqualTo(key("select foo", true, ""));
assertThat(key("select foo", true, "").hashCode()).isEqualTo(key("select foo", true, "").hashCode());
}
@Test
public void test_notEquals_diff_sql() {
assertThat(key("select foo", true, true, "")).isNotEqualTo(key("select bar", true, true, ""));
assertThat(key("select foo", true, true, "").hashCode()).isNotEqualTo(key("select bar", true, true, "").hashCode());
assertThat(key("select foo", true, "")).isNotEqualTo(key("select bar", true, ""));
assertThat(key("select foo", true, "").hashCode()).isNotEqualTo(key("select bar", true, "").hashCode());
}
@Test
public void test_notEquals_diff_rawSqlFlag() {
assertThat(key("select foo", true, true, "")).isNotEqualTo(key("select foo", false, true, ""));
assertThat(key("select foo", true, true, "").hashCode()).isNotEqualTo(key("select foo", false, true, "").hashCode());
assertThat(key("select foo", true, "")).isNotEqualTo(key("select foo", false, ""));
assertThat(key("select foo", true, "").hashCode()).isNotEqualTo(key("select foo", false, "").hashCode());
}
@Test
public void test_notEquals_diff_rowNumberIncluded() {
assertThat(key("select foo", true, true, "")).isNotEqualTo(key("select foo", true, false, ""));
assertThat(key("select foo", true, true, "").hashCode()).isNotEqualTo(key("select foo", true, false, "").hashCode());
}
@Test
public void test_notEquals_diff_logWhereSql() {
assertThat(key("select foo", true, true, "")).isNotEqualTo(key("select foo", true, true, "a"));
assertThat(key("select foo", true, true, "").hashCode()).isNotEqualTo(key("select foo", true, true, "a").hashCode());
assertThat(key("select foo", true, "")).isNotEqualTo(key("select foo", true, "a"));
assertThat(key("select foo", true, "").hashCode()).isNotEqualTo(key("select foo", true, "a").hashCode());
}
private RawSqlQueryPlanKey key(String sql, boolean rawSql, boolean rowNumberIncluded, String logWhereSql) {
return new RawSqlQueryPlanKey(sql, rawSql, rowNumberIncluded, logWhereSql);
private RawSqlQueryPlanKey key(String sql, boolean rawSql, String logWhereSql) {
return new RawSqlQueryPlanKey(sql, rawSql, logWhereSql);
}
}