From 02cfe20225d230f82878ac453fb222351f2dc292 Mon Sep 17 00:00:00 2001 From: Michael Minella Date: Fri, 15 May 2015 14:11:31 -0500 Subject: [PATCH] Refactored to keep column aliases in certain conditions The solution for BATCH-2079 was too agressive in that it removed table references from columns in places that ended up in where clauses. Since SQL does not support the use of column aliases in where clauses, the table references are needed. This fix should address adding the aliases back where needed, while keeping them out in the windowing paging query use cases where they were problematic. BATCH-2360 --- .../database/support/SqlPagingQueryUtils.java | 12 +++++----- .../SqlWindowingPagingQueryProvider.java | 14 +++++++++++- .../MySqlPagingQueryProviderTests.java | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java index 4e2848f61..651a18435 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java @@ -16,14 +16,14 @@ package org.springframework.batch.item.database.support; -import org.springframework.batch.item.database.Order; -import org.springframework.util.StringUtils; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import org.springframework.batch.item.database.Order; +import org.springframework.util.StringUtils; + /** * Utility class that generates the actual SQL statements used by query * providers. @@ -246,7 +246,7 @@ public class SqlPagingQueryUtils { * @return a String that can be appended to an ORDER BY clause. */ public static String buildSortClause(AbstractSqlPagingQueryProvider provider) { - return buildSortClause(provider.getSortKeysWithoutAliases()); + return buildSortClause(provider.getSortKeys()); } /** @@ -285,7 +285,7 @@ public class SqlPagingQueryUtils { */ public static void buildSortConditions( AbstractSqlPagingQueryProvider provider, StringBuilder sql) { - List> keys = new ArrayList>(provider.getSortKeysWithoutAliases().entrySet()); + List> keys = new ArrayList>(provider.getSortKeys().entrySet()); List clauses = new ArrayList(); for(int i = 0; i < keys.size(); i++) { @@ -336,7 +336,7 @@ public class SqlPagingQueryUtils { String prefix = ""; - for (Map.Entry sortKey : provider.getSortKeysWithoutAliases().entrySet()) { + for (Map.Entry sortKey : provider.getSortKeys().entrySet()) { select.append(prefix); prefix = ", "; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java index b957b3c15..e884c456f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java @@ -149,7 +149,7 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi protected String getOverClause() { StringBuilder sql = new StringBuilder(); - sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this)); + sql.append(" ORDER BY ").append(buildSortClause(this)); return sql.toString(); } @@ -161,4 +161,16 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi protected String getOverSubstituteClauseEnd() { return ""; } + + + /** + * Generates ORDER BY attributes based on the sort keys. + * + * @param provider + * @return a String that can be appended to an ORDER BY clause. + */ + private String buildSortClause(AbstractSqlPagingQueryProvider provider) { + return SqlPagingQueryUtils.buildSortClause(provider.getSortKeysWithoutAliases()); + } + } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java index 3167cca08..6897fbd0f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java @@ -17,8 +17,12 @@ package org.springframework.batch.item.database.support; import static org.junit.Assert.assertEquals; +import java.util.HashMap; + import org.junit.Test; +import org.springframework.batch.item.database.Order; + /** * @author Thomas Risberg * @author Michael Minella @@ -94,6 +98,24 @@ public class MySqlPagingQueryProviderTests extends AbstractSqlPagingQueryProvide assertEquals(sql, s); } + @Test + public void testFirstPageSqlWithAliases() { + this.pagingQueryProvider = new MySqlPagingQueryProvider(); + this.pagingQueryProvider.setSelectClause("SELECT owner.id as ownerid, first_name, last_name, dog_name "); + this.pagingQueryProvider.setFromClause("FROM dog_owner owner INNER JOIN dog ON owner.id = dog.id "); + this.pagingQueryProvider.setSortKeys(new HashMap() {{ + put("owner.id", Order.ASCENDING); + }}); + + String firstPage = this.pagingQueryProvider.generateFirstPageQuery(5); + String jumpToItemQuery = this.pagingQueryProvider.generateJumpToItemQuery(7, 5); + String remainingPagesQuery = this.pagingQueryProvider.generateRemainingPagesQuery(5); + + assertEquals("SELECT owner.id as ownerid, first_name, last_name, dog_name FROM dog_owner owner INNER JOIN dog ON owner.id = dog.id ORDER BY owner.id ASC LIMIT 5", firstPage); + assertEquals("SELECT owner.id FROM dog_owner owner INNER JOIN dog ON owner.id = dog.id ORDER BY owner.id ASC LIMIT 4, 1", jumpToItemQuery); + assertEquals("SELECT owner.id as ownerid, first_name, last_name, dog_name FROM dog_owner owner INNER JOIN dog ON owner.id = dog.id WHERE ((owner.id > ?)) ORDER BY owner.id ASC LIMIT 5", remainingPagesQuery); + } + @Override public String getFirstPageSqlWithMultipleSortKeys() { return "SELECT id, name, age FROM foo WHERE bar = 1 ORDER BY name ASC, id DESC LIMIT 100";