HHH-18461 Fix native query doesn't respect `query.setFirstResult(0)`

Align to JPQL query, generated sql should contain `offset ? rows` and pass `0` as parameter.
This commit is contained in:
Yanming Zhou 2024-08-05 17:06:54 +08:00
parent afca93158e
commit b80d21b233
9 changed files with 31 additions and 28 deletions

View File

@ -48,7 +48,7 @@ public class AltibaseDialectTestCase extends BaseUnitTestCase {
public void testSelectWithLimitOnly() {
assertEquals( "select c1, c2 from t1 order by c1, c2 desc limit ?",
dialect.getLimitHandler().processSql("select c1, c2 from t1 order by c1, c2 desc",
toRowSelection( 0, 15 ) ).toLowerCase( Locale.ROOT));
toRowSelection( null, 15 ) ).toLowerCase( Locale.ROOT));
}
@Test
@ -65,7 +65,7 @@ public class AltibaseDialectTestCase extends BaseUnitTestCase {
null ).toLowerCase(Locale.ROOT));
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );

View File

@ -42,7 +42,7 @@ public class DerbyDialectTestCase {
final String input = "select * from tablename t where t.cat = 5";
final String expected = "select * from tablename t where t.cat = 5 fetch first ? rows only";
final String actual = new DerbyDialect().getLimitHandler().processSql( input, toRowSelection( 0, limit ) );
final String actual = new DerbyDialect().getLimitHandler().processSql( input, toRowSelection( null, limit ) );
assertEquals( expected, actual );
}
@ -101,7 +101,7 @@ public class DerbyDialectTestCase {
scope.inSession( s -> Assertions.assertEquals( 69, s.createSelectionQuery( "select count from Constrained", int.class).getSingleResult()));
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );

View File

@ -29,7 +29,7 @@ public class DerbyLegacyDialectTestCase extends BaseUnitTestCase {
final String input = "select * from tablename t where t.cat = 5";
final String expected = "select * from tablename t where t.cat = 5 fetch first " + limit + " rows only";
final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( 0, limit ) );
final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( null, limit ) );
assertEquals( expected, actual );
}
@ -84,7 +84,7 @@ public class DerbyLegacyDialectTestCase extends BaseUnitTestCase {
assertEquals( expected, actual );
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );

View File

@ -20,15 +20,15 @@ class FirebirdDialectTest {
@ParameterizedTest
@CsvSource(useHeadersInDisplayName = true, value = {
"major, minor, offset, limit, expectedSQL",
"2, 5, 0, 10, select first ? * from tablename t where t.cat = 5",
"2, 5, , 10, select first ? * from tablename t where t.cat = 5",
"2, 5, 10, 0, select skip ? * from tablename t where t.cat = 5",
"2, 5, 5, 10, select first ? skip ? * from tablename t where t.cat = 5",
"3, 0, 0, 10, select * from tablename t where t.cat = 5 fetch first ? rows only",
"3, 0, , 10, select * from tablename t where t.cat = 5 fetch first ? rows only",
"3, 0, 10, 0, select * from tablename t where t.cat = 5 offset ? rows",
"3, 0, 5, 10, select * from tablename t where t.cat = 5 offset ? rows fetch next ? rows only"
})
@JiraKey( "HHH-18213" )
void insertOffsetLimitClause(int major, int minor, int offset, int limit, String expectedSql) {
void insertOffsetLimitClause(int major, int minor, Integer offset, Integer limit, String expectedSql) {
String input = "select * from tablename t where t.cat = 5";
FirebirdDialect dialect = new FirebirdDialect( DatabaseVersion.make( major, minor ) );
String actual = dialect.getLimitHandler().processSql( input, new Limit( offset, limit ) );

View File

@ -168,7 +168,7 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase {
"select top(?) col0_.CONTENTID as CONTENT1_12_ " +
"where col0_.CONTENTTYPE='PAGE' and (col0_.CONTENTID in " +
"(select distinct col2_.PREVVER from CONTENT col2_ where (col2_.PREVVER is not null)))",
dialect.getLimitHandler().processSql( selectDistinctSubselectSQL, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( selectDistinctSubselectSQL, toRowSelection( null, 5 ) )
);
}
@ -254,7 +254,7 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select top(?) product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
"from Product2 product2x0_ order by product2x0_.id",
dialect.getLimitHandler().processSql( query, toRowSelection( 0, 1 ) )
dialect.getLimitHandler().processSql( query, toRowSelection( null, 1 ) )
);
final String distinctQuery = "select distinct product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
@ -263,7 +263,7 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select distinct top(?) product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
"from Product2 product2x0_ order by product2x0_.id",
dialect.getLimitHandler().processSql( distinctQuery, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( distinctQuery, toRowSelection( null, 5 ) )
);
}
@ -406,14 +406,14 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select top(?) t1.c1 as col_0_0, (select case when count(t2.c1)>0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC",
dialect.getLimitHandler().processSql( query, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( query, toRowSelection( null, 5 ) )
);
}
@Test
@TestForIssue(jiraKey = "HHH-8916")
public void testGetLimitStringUsingCTEQueryNoOffset() {
Limit selection = toRowSelection( 0, 5 );
Limit selection = toRowSelection( null, 5 );
// test top-based CTE with single CTE query_ definition with no odd formatting
final String query1 = "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT c1, c2 FROM a";
@ -635,7 +635,7 @@ public class SQLServer2005DialectTestCase extends BaseUnitTestCase {
assertEquals( expectedLockHint, lockHint );
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );

View File

@ -170,7 +170,7 @@ public class SQLServer2008DialectTestCase extends BaseUnitTestCase {
"select top(?) col0_.CONTENTID as CONTENT1_12_ " +
"where col0_.CONTENTTYPE='PAGE' and (col0_.CONTENTID in " +
"(select distinct col2_.PREVVER from CONTENT col2_ where (col2_.PREVVER is not null)))",
dialect.getLimitHandler().processSql( selectDistinctSubselectSQL, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( selectDistinctSubselectSQL, toRowSelection( null, 5 ) )
);
}
@ -256,7 +256,7 @@ public class SQLServer2008DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select top(?) product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
"from Product2 product2x0_ order by product2x0_.id",
dialect.getLimitHandler().processSql( query, toRowSelection( 0, 1 ) )
dialect.getLimitHandler().processSql( query, toRowSelection( null, 1 ) )
);
final String distinctQuery = "select distinct product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
@ -265,7 +265,7 @@ public class SQLServer2008DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select distinct top(?) product2x0_.id as id0_, product2x0_.description as descript2_0_ " +
"from Product2 product2x0_ order by product2x0_.id",
dialect.getLimitHandler().processSql( distinctQuery, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( distinctQuery, toRowSelection( null, 5 ) )
);
}
@ -408,14 +408,14 @@ public class SQLServer2008DialectTestCase extends BaseUnitTestCase {
assertEquals(
"select top(?) t1.c1 as col_0_0, (select case when count(t2.c1)>0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC",
dialect.getLimitHandler().processSql( query, toRowSelection( 0, 5 ) )
dialect.getLimitHandler().processSql( query, toRowSelection( null, 5 ) )
);
}
@Test
@JiraKey("HHH-8916")
public void testGetLimitStringUsingCTEQueryNoOffset() {
Limit selection = toRowSelection( 0, 5 );
Limit selection = toRowSelection( null, 5 );
// test top-based CTE with single CTE query_ definition with no odd formatting
final String query1 = "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT c1, c2 FROM a";
@ -637,7 +637,7 @@ public class SQLServer2008DialectTestCase extends BaseUnitTestCase {
assertEquals( expectedLockHint, lockHint );
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );

View File

@ -230,8 +230,7 @@ public abstract class AbstractLimitHandler implements LimitHandler {
*/
public static boolean hasFirstRow(Limit limit) {
return limit != null
&& limit.getFirstRow() != null
&& limit.getFirstRow() > 0;
&& limit.getFirstRow() != null;
}
/**

View File

@ -50,7 +50,7 @@ public abstract class AbstractLimitHandlerTest {
protected abstract LimitHandler getLimitHandler();
protected Limit getLimit() {
return new Limit(0, 10);
return new Limit(null, 10);
}
protected String getLimitClause() {
@ -64,9 +64,13 @@ public abstract class AbstractLimitHandlerTest {
}
else if (hasFirstRow(limit)) {
return " offset " + (oflh.supportsVariableLimit() ? "?" : String.valueOf(limit.getFirstRow())) + " rows";
} else {
}
else if (hasMaxRows(limit)) {
return " fetch first " + (oflh.supportsVariableLimit() ? "?" : String.valueOf(limit.getMaxRows())) + " rows only";
}
else {
return "";
}
}
return " limit ?";
}

View File

@ -45,7 +45,7 @@ public class SQLServer2012DialectTestCase extends BaseUnitTestCase {
final String input = "select distinct f1 as f53245 from table846752 order by f234, f67 desc";
assertEquals(
input + " offset 0 rows fetch first ? rows only",
dialect.getLimitHandler().processSql( input, toRowSelection( 0, 10 ) ).toLowerCase( Locale.ROOT )
dialect.getLimitHandler().processSql( input, toRowSelection( null, 10 ) ).toLowerCase( Locale.ROOT )
);
}
@ -65,7 +65,7 @@ public class SQLServer2012DialectTestCase extends BaseUnitTestCase {
final String input = "select f1 from table";
assertEquals(
"select f1 from table order by @@version offset 0 rows fetch first ? rows only",
dialect.getLimitHandler().processSql( input, toRowSelection( 0, 10 ) ).toLowerCase( Locale.ROOT )
dialect.getLimitHandler().processSql( input, toRowSelection( null, 10 ) ).toLowerCase( Locale.ROOT )
);
}
@ -79,7 +79,7 @@ public class SQLServer2012DialectTestCase extends BaseUnitTestCase {
);
}
private Limit toRowSelection(int firstRow, int maxRows) {
private Limit toRowSelection(Integer firstRow, Integer maxRows) {
final Limit selection = new Limit();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );