}
if (!isRootFeature) {
// also we always need to apply paging for the last queryJoin since it is the join to
// the root feature type (where the original paging parameters come from)
QueryJoin lastJoin = query.getQueryJoins()
.get(query.getQueryJoins().size() - 1);
pagingApplied = applyPaging(lastJoin, sql, pkColumnNames, lastTableName,
lastTableAlias, tableNames, toSQL, filter, ids);
}
if (lastSortBy != null
&& (lastSortBy.length > 0 || !lastPkColumnNames.isEmpty())) {
//we will use another join for the filter
//assuming that the last sort by specifies the ID of the parent feature
//this way we will ensure that if the table is denormalized, that all rows
//with the same ID are included (for multi-valued features)
StringBuffer sortBySQL = new StringBuffer();
sortBySQL.append(" INNER JOIN ( SELECT DISTINCT ");
boolean hasSortBy = false;
for (int i=0; i < lastSortBy.length; i++) {
if (!ids.contains(lastSortBy[i].getPropertyName().toString())) {
// skip if inner join is already done in paging
getDataStore().dialect.encodeColumnName(null, lastSortBy[i].getPropertyName().getPropertyName(), sortBySQL);
if (i < lastSortBy.length-1) sortBySQL.append(",");
sortBySQL.append(" FROM ");
getDataStore().encodeTableName(lastTableName, sortBySQL, query.getHints());
sortBySQL.append(" ").append(toSQL.encodeToString(filter));
sortBySQL.append(" ) ");
getDataStore().dialect.encodeTableName(TEMP_FILTER_ALIAS, sortBySQL);
sortBySQL.append(" ON ( ");
encodeColumnName2(lastSortBy[i].getPropertyName().getPropertyName(), lastTableAlias , sortBySQL, null);
sortBySQL.append(" = ");
encodeColumnName2(lastSortBy[i].getPropertyName().getPropertyName(), TEMP_FILTER_ALIAS , sortBySQL, null);
if (i < lastSortBy.length-1) {
sortBySQL.append(" AND ");
}
hasSortBy = true;
}
}
if (lastSortBy.length == 0) {
// GEOT-4554: if ID expression is not specified, use PK
int i = 0;
for (String pk : lastPkColumnNames) {
if (!ids.contains(pk)) {
getDataStore().dialect.encodeColumnName(null, pk, sortBySQL);
if (i < lastPkColumnNames.size() - 1)
sortBySQL.append(",");
sortBySQL.append(" FROM ");
getDataStore().encodeTableName(lastTableName, sortBySQL, query.getHints());
sortBySQL.append(" ").append(toSQL.encodeToString(filter));
sortBySQL.append(" ) ");
getDataStore().dialect.encodeTableName(TEMP_FILTER_ALIAS, sortBySQL);
sortBySQL.append(" ON ( ");
encodeColumnName2(pk, lastTableAlias, sortBySQL, null);
sortBySQL.append(" = ");
encodeColumnName2(pk, TEMP_FILTER_ALIAS, sortBySQL, null);
if (i < lastPkColumnNames.size() - 1) {
sortBySQL.append(" AND ");
}
i++;
hasSortBy = true;
}
}
}
if (hasSortBy) {
sql.append(sortBySQL).append(" ) ");
}
} else if (!pagingApplied) {
toSQL.setFieldEncoder(new JoiningFieldEncoder(curTypeName));
sql.append(" ").append(toSQL.encodeToString(filter));
}
} catch (FilterToSQLException e) {
throw new RuntimeException(e);
}
} else {
if (isRootFeature && query.isDenormalised()) {
// apply inner join for paging to root feature
pagingApplied = applyPaging(query, sql, pkColumnNames, featureType.getTypeName(), featureType.getTypeName(),
tableNames, null, null, null);
}
if (!isRootFeature) {
// also we always need to apply paging for the last queryJoin since it is the join to
// the root feature type (where the original paging parameters come from)
QueryJoin lastJoin = query.getQueryJoins().get(query.getQueryJoins().size() - 1);
String lastTableAlias = aliases[query.getQueryJoins().size() - 1] == null ? lastJoin
.getJoiningTypeName() : aliases[query.getQueryJoins().size() - 1];
pagingApplied = applyPaging(lastJoin, sql, pkColumnNames, lastJoin.getJoiningTypeName(), lastTableAlias,
tableNames, null, null, null);
}
}
//sorting