#1841 - SqlServer findCount with @Aggregation gives SQLException:No column name was specified for column 2 of 'c'

This commit is contained in:
rob bygrave
2019-10-11 20:18:18 +13:00
parent b665d8375c
commit e00aa479ae
6 changed files with 29 additions and 32 deletions
@@ -148,8 +148,6 @@ public class DatabasePlatform {
protected String columnAliasPrefix = "c";
protected String tableAliasPlaceHolder = "${ta}";
/**
* Use a BackTick ` at the beginning and end of table or column names that you
* want to use quoted identifiers for. The backticks get converted to the
@@ -183,6 +181,7 @@ public class DatabasePlatform {
protected boolean idInExpandedForm;
protected boolean selectCountWithAlias;
protected boolean selectCountWithColumnAlias;
/**
* If set then use the FORWARD ONLY hint when creating ResultSets for
@@ -478,20 +477,6 @@ public class DatabasePlatform {
this.columnAliasPrefix = columnAliasPrefix;
}
/**
* Return the table alias placeholder.
*/
public String getTableAliasPlaceHolder() {
return tableAliasPlaceHolder;
}
/**
* Set the table alias placeholder.
*/
public void setTableAliasPlaceHolder(String tableAliasPlaceHolder) {
this.tableAliasPlaceHolder = tableAliasPlaceHolder;
}
/**
* Return the close quote for quoted identifiers.
*/
@@ -684,6 +669,14 @@ public class DatabasePlatform {
return selectCountWithAlias;
}
/**
* Return true if select count with subquery needs column alias (SQL Server).
*/
public boolean isSelectCountWithColumnAlias() {
return selectCountWithColumnAlias;
}
public String completeSql(String sql, Query<?> query) {
if (query.isForUpdate()) {
sql = withForUpdate(sql, query.getForUpdateMode());
@@ -28,6 +28,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
this.persistBatchOnCascade = PersistBatch.NONE;
this.idInExpandedForm = true;
this.selectCountWithAlias = true;
this.selectCountWithColumnAlias = true;
this.sqlLimiter = new SqlServerSqlLimiter();
this.basicSqlLimiter = new SqlServerBasicSqlLimiter();
this.historySupport = new SqlServerHistorySupport();
@@ -43,9 +43,7 @@ import java.util.List;
*/
class CQueryBuilder {
final String tableAliasPlaceHolder;
final String columnAliasPrefix;
private final String columnAliasPrefix;
private final SqlLimiter sqlLimiter;
private final CQueryBuilderRawSql rawSqlHandler;
private final Binder binder;
@@ -55,6 +53,7 @@ class CQueryBuilder {
private final CQueryHistorySupport historySupport;
private final CQueryDraftSupport draftSupport;
private final DatabasePlatform dbPlatform;
private final boolean selectCountWithColumnAlias;
/**
* Create the SqlGenSelect.
@@ -64,11 +63,11 @@ class CQueryBuilder {
this.binder = binder;
this.draftSupport = draftSupport;
this.historySupport = historySupport;
this.tableAliasPlaceHolder = dbPlatform.getTableAliasPlaceHolder();
this.columnAliasPrefix = dbPlatform.getColumnAliasPrefix();
this.sqlLimiter = dbPlatform.getSqlLimiter();
this.rawSqlHandler = new CQueryBuilderRawSql(sqlLimiter, dbPlatform);
this.selectCountWithAlias = dbPlatform.isSelectCountWithAlias();
this.selectCountWithColumnAlias = dbPlatform.isSelectCountWithColumnAlias();
}
/**
@@ -86,7 +85,6 @@ class CQueryBuilder {
sb.append(".");
sb.append(token.trim());
}
return sb.toString();
}
@@ -273,7 +271,7 @@ class CQueryBuilder {
predicates.prepare(true);
SqlTree sqlTree = createSqlTree(request, predicates);
SqlTree sqlTree = createSqlTree(request, predicates, selectCountWithColumnAlias && withAgg);
if (SpiQuery.TemporalMode.CURRENT == query.getTemporalMode()) {
sqlTree.addSoftDeletePredicate(query);
}
@@ -399,6 +397,10 @@ class CQueryBuilder {
* </p>
*/
private SqlTree createSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
return createSqlTree(request, predicates, false);
}
private SqlTree createSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates, boolean forceColumnAlias) {
if (request.isNativeSql()) {
return createNativeSqlTree(request, predicates);
@@ -406,7 +408,8 @@ class CQueryBuilder {
if (request.isRawSql()) {
return createRawSqlSqlTree(request, predicates);
}
return new SqlTreeBuilder(this, request, predicates).build();
String colAliasPrefix = forceColumnAlias ? "c" : columnAliasPrefix;
return new SqlTreeBuilder(colAliasPrefix, this, request, predicates).build();
}
private String nativeQueryPaging(SpiQuery<?> query, String sql) {
@@ -16,7 +16,7 @@ class DefaultDbSqlContext implements DbSqlContext {
private static final String PERIOD = ".";
private static final int STRING_BUILDER_INITIAL_CAPACITY = 140;
private final String tableAliasPlaceHolder;
private static final String tableAliasPlaceHolder = "${ta}";
private final String columnAliasPrefix;
@@ -56,14 +56,11 @@ class DefaultDbSqlContext implements DbSqlContext {
/**
* Construct for SELECT clause (with column alias settings).
*/
DefaultDbSqlContext(SqlTreeAlias alias, CQueryBuilder builder,
boolean alwaysUseColumnAlias, CQueryHistorySupport historySupport,
DefaultDbSqlContext(SqlTreeAlias alias, String columnAliasPrefix, CQueryHistorySupport historySupport,
CQueryDraftSupport draftSupport, String fromForUpdate) {
this.alias = alias;
this.tableAliasPlaceHolder = builder.tableAliasPlaceHolder;
this.columnAliasPrefix = builder.columnAliasPrefix;
this.useColumnAlias = columnAliasPrefix != null && alwaysUseColumnAlias;
this.columnAliasPrefix = columnAliasPrefix;
this.useColumnAlias = columnAliasPrefix != null;
this.draftSupport = draftSupport;
this.historySupport = historySupport;
this.historyQuery = (historySupport != null);
@@ -96,7 +96,7 @@ public final class SqlTreeBuilder {
* support the where and/or order by clause. If so these extra joins are added
* to the root node.
*/
SqlTreeBuilder(CQueryBuilder builder, OrmQueryRequest<?> request, CQueryPredicates predicates) {
SqlTreeBuilder(String columnAliasPrefix, CQueryBuilder builder, OrmQueryRequest<?> request, CQueryPredicates predicates) {
this.rawSql = false;
this.rawNoId = false;
@@ -116,7 +116,8 @@ public final class SqlTreeBuilder {
String fromForUpdate = builder.fromForUpdate(query);
CQueryHistorySupport historySupport = builder.getHistorySupport(query);
CQueryDraftSupport draftSupport = builder.getDraftSupport(query);
this.ctx = new DefaultDbSqlContext(alias, builder, !subQuery, historySupport, draftSupport, fromForUpdate);
String colAlias = subQuery ? null : columnAliasPrefix;
this.ctx = new DefaultDbSqlContext(alias, colAlias, historySupport, draftSupport, fromForUpdate);
}
/**