HHH-16589 In clause padding can no longer cause in clauses to exceed Dialect.getInExpressionCountLimit
This commit is contained in:
parent
4e7c5df4fe
commit
56955367ba
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.query;
|
package org.hibernate.orm.test.query;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ import org.junit.jupiter.api.Test;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@Setting(name = AvailableSettings.IN_CLAUSE_PARAMETER_PADDING, value = "true"),
|
@Setting(name = AvailableSettings.IN_CLAUSE_PARAMETER_PADDING, value = "true"),
|
||||||
@Setting(name = AvailableSettings.DIALECT_NATIVE_PARAM_MARKERS, value = "false"),
|
@Setting(name = AvailableSettings.DIALECT_NATIVE_PARAM_MARKERS, value = "false"),
|
||||||
},
|
},
|
||||||
settingProviders ={
|
settingProviders = {
|
||||||
@SettingProvider(
|
@SettingProvider(
|
||||||
settingName = AvailableSettings.DIALECT,
|
settingName = AvailableSettings.DIALECT,
|
||||||
provider = MaxInExpressionParameterPaddingTest.DialectProvider.class
|
provider = MaxInExpressionParameterPaddingTest.DialectProvider.class
|
||||||
|
@ -76,20 +79,33 @@ public class MaxInExpressionParameterPaddingTest {
|
||||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
scope.inTransaction( entityManager ->
|
scope.inTransaction( entityManager -> entityManager
|
||||||
entityManager.createQuery( "select p from Person p where p.id in :ids" )
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
.setParameter( "ids", IntStream.range( 0, MAX_COUNT ).boxed().collect( Collectors.toList() ) )
|
.setParameter( "ids", integerRangeList( 0, 5 ) )
|
||||||
.getResultList()
|
.getResultList() );
|
||||||
);
|
|
||||||
|
|
||||||
StringBuilder expectedInClause = new StringBuilder();
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
expectedInClause.append( "in (?" );
|
expectedInClause.append( "where p1_0.id in " );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
appendInClause( expectedInClause, 8 );
|
||||||
expectedInClause.append( ",?" );
|
|
||||||
}
|
|
||||||
expectedInClause.append( ")" );
|
|
||||||
|
|
||||||
assertTrue( statementInspector.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInClauseParameterNoPaddingAtLimit(EntityManagerFactoryScope scope) {
|
||||||
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
|
statementInspector.clear();
|
||||||
|
|
||||||
|
scope.inTransaction( entityManager -> entityManager
|
||||||
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
|
.setParameter( "ids", integerRangeList( 0, MAX_COUNT ) )
|
||||||
|
.getResultList() );
|
||||||
|
|
||||||
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
|
expectedInClause.append( "where p1_0.id in " );
|
||||||
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
|
|
||||||
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestForIssue(jiraKey = "HHH-14109")
|
@TestForIssue(jiraKey = "HHH-14109")
|
||||||
|
@ -98,24 +114,16 @@ public class MaxInExpressionParameterPaddingTest {
|
||||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
scope.inTransaction(
|
scope.inTransaction( entityManager -> entityManager
|
||||||
entityManager ->
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
entityManager.createQuery(
|
.setParameter( "ids", integerRangeList( 0, 10 ) )
|
||||||
"select p from Person p where p.id in :ids" )
|
.getResultList() );
|
||||||
.setParameter( "ids", IntStream.range( 0, 10 )
|
|
||||||
.boxed()
|
|
||||||
.collect( Collectors.toList() ) )
|
|
||||||
.getResultList()
|
|
||||||
);
|
|
||||||
|
|
||||||
StringBuilder expectedInClause = new StringBuilder();
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
expectedInClause.append( "in (?" );
|
expectedInClause.append( "where p1_0.id in " );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
expectedInClause.append( ",?" );
|
|
||||||
}
|
|
||||||
expectedInClause.append( ")" );
|
|
||||||
|
|
||||||
assertTrue( statementInspector.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -123,25 +131,38 @@ public class MaxInExpressionParameterPaddingTest {
|
||||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
scope.inTransaction(
|
scope.inTransaction( entityManager -> entityManager
|
||||||
entityManager ->
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
entityManager.createQuery(
|
.setParameter( "ids", integerRangeList( 0, 16 ) )
|
||||||
"select p from Person p where p.id in :ids" )
|
.getResultList() );
|
||||||
.setParameter( "ids", IntStream.range( 0, 16 )
|
|
||||||
.boxed()
|
|
||||||
.collect( Collectors.toList() ) )
|
|
||||||
.getResultList()
|
|
||||||
);
|
|
||||||
|
|
||||||
StringBuilder expectedInClause = new StringBuilder();
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
expectedInClause.append( "in (?" );
|
expectedInClause.append( "where (p1_0.id in " );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
expectedInClause.append( ",?" );
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
}
|
appendInClause( expectedInClause, 1 );
|
||||||
expectedInClause.append( ")" );
|
expectedInClause.append( ')' );
|
||||||
expectedInClause.append( " or p1_0.id in (?)" );
|
|
||||||
|
|
||||||
assertTrue( statementInspector.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInClauseParameterSplittingAfterLimitNotIn(EntityManagerFactoryScope scope) {
|
||||||
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
|
statementInspector.clear();
|
||||||
|
|
||||||
|
scope.inTransaction( entityManager -> entityManager
|
||||||
|
.createQuery( "select p from Person p where p.id not in :ids" )
|
||||||
|
.setParameter( "ids", integerRangeList( 0, 16 ) )
|
||||||
|
.getResultList() );
|
||||||
|
|
||||||
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
|
expectedInClause.append( "where p1_0.id not in " );
|
||||||
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
|
expectedInClause.append( " and p1_0.id not in " );
|
||||||
|
appendInClause( expectedInClause, 1 );
|
||||||
|
|
||||||
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -149,25 +170,19 @@ public class MaxInExpressionParameterPaddingTest {
|
||||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
scope.inTransaction(
|
scope.inTransaction( entityManager -> entityManager
|
||||||
entityManager ->
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
entityManager.createQuery(
|
.setParameter( "ids", integerRangeList( 0, 18 ) )
|
||||||
"select p from Person p where p.id in :ids" )
|
.getResultList() );
|
||||||
.setParameter( "ids", IntStream.range( 0, 18 )
|
|
||||||
.boxed()
|
|
||||||
.collect( Collectors.toList() ) )
|
|
||||||
.getResultList()
|
|
||||||
);
|
|
||||||
|
|
||||||
StringBuilder expectedInClause = new StringBuilder();
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
expectedInClause.append( "in (?" );
|
expectedInClause.append( "where (p1_0.id in " );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
expectedInClause.append( ",?" );
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
}
|
appendInClause( expectedInClause, 4 );
|
||||||
expectedInClause.append( ")" );
|
expectedInClause.append( ')' );
|
||||||
expectedInClause.append( " or p1_0.id in (?,?,?,?)" );
|
|
||||||
|
|
||||||
assertTrue( statementInspector.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -175,31 +190,58 @@ public class MaxInExpressionParameterPaddingTest {
|
||||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
statementInspector.clear();
|
statementInspector.clear();
|
||||||
|
|
||||||
scope.inTransaction(
|
scope.inTransaction( entityManager -> entityManager
|
||||||
entityManager ->
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
entityManager.createQuery(
|
.setParameter( "ids", integerRangeList( 0, 33 ) )
|
||||||
"select p from Person p where p.id in :ids" )
|
.getResultList() );
|
||||||
.setParameter( "ids", IntStream.range( 0, 33 )
|
|
||||||
.boxed()
|
|
||||||
.collect( Collectors.toList() ) )
|
|
||||||
.getResultList()
|
|
||||||
);
|
|
||||||
|
|
||||||
StringBuilder expectedInClause = new StringBuilder();
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
expectedInClause.append( "in (?" );
|
expectedInClause.append( "where (p1_0.id in " );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
expectedInClause.append( ",?" );
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
}
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
expectedInClause.append( ")" );
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
expectedInClause.append( " or p1_0.id in (?");
|
appendInClause( expectedInClause, 4 );
|
||||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
expectedInClause.append( ')' );
|
||||||
expectedInClause.append( ",?" );
|
|
||||||
}
|
|
||||||
expectedInClause.append( ")" );
|
|
||||||
expectedInClause.append( " or p1_0.id in (?,?,?,?)" );
|
|
||||||
|
|
||||||
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
assertTrue( statementInspector.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
@TestForIssue(jiraKey = "HHH-16589")
|
||||||
|
@Test
|
||||||
|
public void testInClauseParameterSplittingAfterLimit4(EntityManagerFactoryScope scope) {
|
||||||
|
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
|
statementInspector.clear();
|
||||||
|
|
||||||
|
scope.inTransaction( entityManager -> entityManager
|
||||||
|
.createQuery( "select p from Person p where p.id in :ids" )
|
||||||
|
.setParameter( "ids", integerRangeList( 0, 39 ) )
|
||||||
|
.getResultList() );
|
||||||
|
|
||||||
|
StringBuilder expectedInClause = new StringBuilder();
|
||||||
|
expectedInClause.append( "where (p1_0.id in " );
|
||||||
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
|
expectedInClause.append( " or p1_0.id in " );
|
||||||
|
appendInClause( expectedInClause, MAX_COUNT );
|
||||||
|
expectedInClause.append( ')' );
|
||||||
|
|
||||||
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).endsWith( expectedInClause.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Integer> integerRangeList(int start, int end) {
|
||||||
|
return IntStream.range( start, end )
|
||||||
|
.boxed()
|
||||||
|
.collect( Collectors.toList() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendInClause(StringBuilder sql, int inClauseSize) {
|
||||||
|
sql.append( "(?" );
|
||||||
|
for ( int i = 1; i < inClauseSize; i++ ) {
|
||||||
|
sql.append( ",?" );
|
||||||
|
}
|
||||||
|
sql.append( ')' );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "Person")
|
@Entity(name = "Person")
|
||||||
|
|
Loading…
Reference in New Issue