From 03520b928f1c69dbf128d083f31b13dc03f7d314 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Mon, 31 Dec 2012 12:24:39 +0100 Subject: [PATCH] HHH-7781 - Fix and test --- .../pagination/SQLServer2005LimitHandler.java | 4 +++- .../dialect/SQLServer2005DialectTestCase.java | 15 +++++++++++++ .../functional/SQLServerDialectTest.java | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/SQLServer2005LimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/SQLServer2005LimitHandler.java index 8930a4d583..32d5d6eb4a 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/SQLServer2005LimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/SQLServer2005LimitHandler.java @@ -179,7 +179,9 @@ public class SQLServer2005LimitHandler extends AbstractLimitHandler { private String getAlias(String expression) { Matcher matcher = ALIAS_PATTERN.matcher( expression ); if ( matcher.find() ) { - return matcher.group( 0 ).replaceFirst( "(?i)\\sas\\s", "" ).trim(); + // Taking advantage of Java regular expressions greedy behavior while extracting the last AS keyword. + // Note that AS keyword can appear in CAST operator, e.g. 'cast(tab1.col1 as varchar(255)) as col1'. + return matcher.group( 0 ).replaceFirst( "(?i)(.)*\\sas\\s", "" ).trim(); } return null; } diff --git a/hibernate-core/src/test/java/org/hibernate/dialect/SQLServer2005DialectTestCase.java b/hibernate-core/src/test/java/org/hibernate/dialect/SQLServer2005DialectTestCase.java index 6ccda4ea77..c0225f0780 100644 --- a/hibernate-core/src/test/java/org/hibernate/dialect/SQLServer2005DialectTestCase.java +++ b/hibernate-core/src/test/java/org/hibernate/dialect/SQLServer2005DialectTestCase.java @@ -153,6 +153,21 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase { ); } + @Test + @TestForIssue(jiraKey = "HHH-7781") + public void testGetLimitStringWithCastOperator() { + final String query = "select cast(lc302_doku6_.redniBrojStavke as varchar(255)) as col_0_0_, lc302_doku6_.dokumentiID as col_1_0_ " + + "from LC302_Dokumenti lc302_doku6_ order by lc302_doku6_.dokumentiID DESC"; + + assertEquals( + "WITH query AS (SELECT inner_query.*, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__ FROM ( " + + "select TOP(?) cast(lc302_doku6_.redniBrojStavke as varchar(255)) as col_0_0_, lc302_doku6_.dokumentiID as col_1_0_ " + + "from LC302_Dokumenti lc302_doku6_ order by lc302_doku6_.dokumentiID DESC ) inner_query ) " + + "SELECT col_0_0_, col_1_0_ FROM query WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?", + dialect.buildLimitHandler( query, toRowSelection( 1, 3 ) ).getProcessedSql() + ); + } + private RowSelection toRowSelection(int firstRow, int maxRows) { RowSelection selection = new RowSelection(); selection.setFirstRow( firstRow ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectTest.java b/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectTest.java index d9e599a5a3..18a7426fd1 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectTest.java @@ -296,6 +296,28 @@ public class SQLServerDialectTest extends BaseCoreFunctionalTestCase { session.close(); } + @Test + @TestForIssue(jiraKey = "HHH-7781") + public void testPaginationWithCastOperator() { + Session session = openSession(); + Transaction tx = session.beginTransaction(); + + for ( int i = 40; i < 50; i++ ) { + session.persist( new Product2( i, "Kit" + i ) ); + } + session.flush(); + session.clear(); + + List list = session.createQuery( "select p.id, cast(p.id as string) as string_id from Product2 p order by p.id" ) + .setFirstResult( 1 ).setMaxResults( 2 ).list(); + assertEquals( 2, list.size() ); + assertArrayEquals( new Object[] { 41, "41" }, list.get( 0 ) ); + assertArrayEquals( new Object[] { 42, "42" }, list.get( 1 ) ); + + tx.rollback(); + session.close(); + } + @Test @TestForIssue(jiraKey = "HHH-3961") public void testLockNowaitSqlServer() throws Exception {