diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JavaTypesArrayTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JavaTypesArrayTest.java index ed2ce57f2..67637735d 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JavaTypesArrayTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JavaTypesArrayTest.java @@ -47,11 +47,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; /** - * Test that we handle arrays as basic types and the @{@link Array} annotation. + * Test that we handle arrays as basic types and the @{@link Array} annotation in combination with @{@link Column}. *

* Specifying the length doesn't seem to have any effect at the moment. - * Except for Postgres: Hibernate ORM will use a different SQL query for the creation of the table, but Postgres will - * ignore the limit anyway. + * We use it when creating the table with Postgres, but Postgres ignore it anyway. */ @Timeout(value = 10, timeUnit = MINUTES) @DisabledFor(value = ORACLE, reason = "Vert.x does not support arrays for Oracle") @@ -72,7 +71,7 @@ protected void addServices(StandardServiceRegistryBuilder builder) { } private static boolean filterCreateTable(String s) { - return s.toLowerCase().startsWith( "create table basic" ); + return s.toLowerCase().startsWith( "create table basic " ); } @Override @@ -387,7 +386,7 @@ public void testBigIntegerArrayType(VertxTestContext context) { testField( context, basic, found -> { assertArrayEquals( dataArray, found.bigIntegerArray ); - validateArrayColumn( "bigIntegerArray", null, null ); + validateArrayColumn( "bigIntegerArray", null, 5000 ); } ); } @@ -401,7 +400,7 @@ public void testBigDecimalArrayType(VertxTestContext context) { assertEquals( dataArray.length, found.bigDecimalArray.length ); assertEquals( 0, dataArray[0].compareTo( found.bigDecimalArray[0] ) ); assertEquals( 0, dataArray[1].compareTo( found.bigDecimalArray[1] ) ); - validateArrayColumn( "bigDecimalArray", null, null ); + validateArrayColumn( "bigDecimalArray", null, 5000 ); } ); } @@ -415,6 +414,7 @@ public void testBigDecimalArrayTypeWithArrayAnnotation(VertxTestContext context) assertEquals( dataArray.length, found.bigDecimalArrayWithArrayAnnotation.length ); assertEquals( 0, dataArray[0].compareTo( found.bigDecimalArrayWithArrayAnnotation[0] ) ); assertEquals( 0, dataArray[1].compareTo( found.bigDecimalArrayWithArrayAnnotation[1] ) ); + validateArrayColumn( "bigDecimalArrayWithArrayAnnotation", 5, 5000 ); } ); } @@ -426,32 +426,60 @@ private void validateArrayColumn(String columnName, Integer arrayLength, Integer // A predicate that checks we apply the right size to the array when required private static Predicate arrayColumnPredicate(String columnName, Integer arrayLength, Integer columnLength) { - final StringBuilder conditionBuilder = new StringBuilder(); - // Only Postgres has a different behaviour if @Array is used - if ( dbType() == POSTGRESQL ) { - conditionBuilder.append( ".*" ); - // Postgres will ignore the length of the array, but we can test the table creation sql query - // and make sure that the limit is defined - - // Example of correct query definition: columnName varchar(123) array[2] - conditionBuilder.append( columnName ).append( " \\w+" ); - if ( columnLength != null ) { - conditionBuilder.append( "\\(" ).append( columnLength ).append( "\\)" ); - } - else { - // for some types we have a default size. For example: `varchar(255)` or `numeric(38,0)` - conditionBuilder.append( "(\\(\\d+(,\\d+)?\\))?" ); - } - conditionBuilder.append( " array" ); - if ( arrayLength != null ) { - conditionBuilder.append( "\\[" ).append( arrayLength ).append( "\\]" ); - } - conditionBuilder.append( ".*" ); + switch ( dbType() ) { + case POSTGRESQL: + case COCKROACHDB: + return postgresPredicate( columnName, arrayLength, columnLength ); + case MYSQL: + case MARIA: + case SQLSERVER: + case DB2: + return mysqlPredicate( columnName, columnLength ); + default: + return s -> true; } - if ( conditionBuilder.length() == 0 ) { - return s -> true; + } + + /** + * For Postgres, we expect arrays to be defined as {@code array}. + *

+ * For example: {@code varchar(255) array[2]} + *

+ */ + private static Predicate postgresPredicate(String columnName, Integer arrayLength, Integer columnLength) { + StringBuilder regexBuilder = new StringBuilder(); + regexBuilder.append( ".*" ); + + regexBuilder.append( columnName ).append( " \\w+" ); + // Column length only affect String types + if ( columnLength != null && columnName.startsWith( "string" ) ) { + regexBuilder.append( "\\(" ).append( columnLength ).append( "\\)" ); + } + else { + // for some types we have a default size. For example: `varchar(255)` or `numeric(38,0)` + regexBuilder.append( "(\\(\\d+(,\\d+)?\\))?" ); + } + regexBuilder.append( " array" ); + if ( arrayLength != null ) { + regexBuilder.append( "\\[" ).append( arrayLength ).append( "\\]" ); + } + regexBuilder.append( ".*" ); + return s -> s.matches( regexBuilder.toString() ); + } + + private static Predicate mysqlPredicate(String columnName, Integer columnLength) { + StringBuilder regexBuilder = new StringBuilder(); + // Example of correct query definition: columnName varbinary(255) + regexBuilder.append( columnName ).append( " varbinary" ).append( "(" ); + if ( columnLength != null ) { + regexBuilder.append( columnLength ); + } + else { + // Default size + regexBuilder.append( 255 ); } - return s -> s.matches( conditionBuilder.toString() ); + regexBuilder.append( ")" ); + return s -> s.contains( regexBuilder.toString() ); } @Entity(name = "Basic")