From 44b5fe1329a8591efedb8618abc59a9ea8d28a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20=C5=A0albaba?= Date: Thu, 17 Jul 2025 16:00:29 +0200 Subject: [PATCH 1/2] Add support for testing with custom EDB image --- docker_db.sh | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/docker_db.sh b/docker_db.sh index e280694fb29f..032ee55cd228 100755 --- a/docker_db.sh +++ b/docker_db.sh @@ -217,37 +217,52 @@ edb() { edb_13() { $CONTAINER_CLI rm -f edb || true - # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator - (cd edb; $CONTAINER_CLI build -t edb-test:13 -f edb13.Dockerfile .) - $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:13 + if [[ -z "${DB_IMAGE_EDB}" ]]; then + DB_IMAGE_EDB="edb-test:13" + # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator + (cd edb; $CONTAINER_CLI build -t edb-test:13 -f edb13.Dockerfile .) + fi + $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB } edb_14() { $CONTAINER_CLI rm -f edb || true - # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator - (cd edb; $CONTAINER_CLI build -t edb-test:14 -f edb14.Dockerfile .) - $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:14 + if [[ -z "${DB_IMAGE_EDB}" ]]; then + DB_IMAGE_EDB="edb-test:14" + # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator + (cd edb; $CONTAINER_CLI build -t edb-test:14 -f edb14.Dockerfile .) + fi + $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB } edb_15() { $CONTAINER_CLI rm -f edb || true - # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator - (cd edb; $CONTAINER_CLI build -t edb-test:15 -f edb15.Dockerfile .) - $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:15 + if [[ -z "${DB_IMAGE_EDB}" ]]; then + DB_IMAGE_EDB="edb-test:15" + # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator + (cd edb; $CONTAINER_CLI build -t edb-test:15 -f edb15.Dockerfile .) + fi + $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB } edb_16() { $CONTAINER_CLI rm -f edb || true - # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator - (cd edb; $CONTAINER_CLI build -t edb-test:16 -f edb16.Dockerfile .) - $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:16 + if [[ -z "${DB_IMAGE_EDB}" ]]; then + DB_IMAGE_EDB="edb-test:16" + # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator + (cd edb; $CONTAINER_CLI build -t edb-test:16 -f edb16.Dockerfile .) + fi + $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB } edb_17() { $CONTAINER_CLI rm -f edb || true - # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator - (cd edb; $CONTAINER_CLI build -t edb-test:17 -f edb17.Dockerfile .) - $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:17 + if [[ -z "${DB_IMAGE_EDB}" ]]; then + DB_IMAGE_EDB="edb-test:17" + # We need to build a derived image because the existing image is mainly made for use by a kubernetes operator + (cd edb; $CONTAINER_CLI build -t edb-test:17 -f edb17.Dockerfile .) + fi + $CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB } db2() { From a7256f8a329a6e58ade9a347157d1a438559ac9c Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Thu, 17 Jul 2025 13:48:44 +0200 Subject: [PATCH 2/2] HHH-19624 Test EDB with EDB drivers --- documentation/documentation.gradle | 1 + hibernate-core/hibernate-core.gradle | 1 + .../hibernate/dialect/PostgreSQLDialect.java | 4 ++ ...stgreSQLCastingIntervalSecondJdbcType.java | 2 +- ...eSQLMultipleTypesOtherContributorTest.java | 7 ++- ...stgreSQLInetTypesOtherContributorTest.java | 6 +-- .../inet/PostgreSQLInetTypesOtherTest.java | 6 +-- .../PostgreSQLFunctionProcedureTest.java | 29 ------------- .../PostgreSQLStoredProcedureTest.java | 29 ------------- .../test/type/PostgresIntervalSecondTest.java | 3 +- ...edDriverManagerConnectionProviderImpl.java | 43 +++++++++++++++++++ .../testing/junit4/CustomRunner.java | 35 +++++++++++++++ .../orm/junit/DialectFeatureChecks.java | 7 +++ .../src/main/groovy/local.databases.gradle | 8 ++-- .../src/main/groovy/local.java-module.gradle | 1 + settings.gradle | 2 + 16 files changed, 110 insertions(+), 74 deletions(-) diff --git a/documentation/documentation.gradle b/documentation/documentation.gradle index 19b3daf882f5..c1ab82d0df3c 100644 --- a/documentation/documentation.gradle +++ b/documentation/documentation.gradle @@ -165,6 +165,7 @@ dependencies { javadocClasspath jakartaLibs.jsonbApi javadocClasspath libs.ant javadocClasspath jdbcLibs.postgresql + javadocClasspath jdbcLibs.edb javadocClasspath libs.jackson javadocClasspath gradleApi() javadocClasspath libs.jacksonXml diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index 3fa4a5d740e2..a417f71604bd 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -42,6 +42,7 @@ dependencies { compileOnly libs.jackson compileOnly libs.jacksonXml compileOnly jdbcLibs.postgresql + compileOnly jdbcLibs.edb testImplementation project(':hibernate-testing') testImplementation project(':hibernate-ant') diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 874d4d52f513..cd394e84b834 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -212,6 +212,10 @@ private static OptionalTableUpdateStrategy determineOptionalTableUpdateStrategy( : PostgreSQLDialect::withoutMerge; } + public PostgreSQLDriverKind getDriverKind() { + return driverKind; + } + @Override protected DatabaseVersion getMinimumSupportedVersion() { return MINIMUM_VERSION; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/type/PostgreSQLCastingIntervalSecondJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/type/PostgreSQLCastingIntervalSecondJdbcType.java index 921f3fae13a0..fbb7c0e12ec1 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/type/PostgreSQLCastingIntervalSecondJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/type/PostgreSQLCastingIntervalSecondJdbcType.java @@ -78,7 +78,7 @@ public void appendWriteExpression( Dialect dialect) { appender.append( '(' ); appender.append( writeExpression ); - appender.append( "*interval'1 second)" ); + appender.append( "*interval'1 second')" ); } @Override diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/PostgreSQLMultipleTypesOtherContributorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/PostgreSQLMultipleTypesOtherContributorTest.java index 01444afe786d..ef1fb59790e8 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/PostgreSQLMultipleTypesOtherContributorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/PostgreSQLMultipleTypesOtherContributorTest.java @@ -16,15 +16,14 @@ import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.boot.spi.MetadataBuilderContributor; import org.hibernate.boot.spi.MetadataBuilderImplementor; -import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.query.NativeQuery; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.type.SqlTypes; import org.hibernate.type.spi.TypeConfiguration; -import org.hibernate.testing.RequiresDialect; - import org.hibernate.orm.test.id.usertype.inet.Inet; import org.hibernate.orm.test.id.usertype.inet.InetJavaType; import org.hibernate.orm.test.id.usertype.inet.InetJdbcType; @@ -40,7 +39,7 @@ /** * @author Vlad Mihalcea */ -@RequiresDialect(PostgreSQLDialect.class) +@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class) public class PostgreSQLMultipleTypesOtherContributorTest extends BaseEntityManagerFunctionalTestCase { @Override diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherContributorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherContributorTest.java index b4a2af695af0..6d348d0e6ea2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherContributorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherContributorTest.java @@ -10,11 +10,11 @@ import org.hibernate.boot.MetadataBuilder; import org.hibernate.boot.spi.MetadataBuilderContributor; import org.hibernate.boot.spi.MetadataBuilderImplementor; -import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.type.spi.TypeConfiguration; -import org.hibernate.testing.RequiresDialect; import org.junit.Test; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; @@ -23,7 +23,7 @@ /** * @author Vlad Mihalcea */ -@RequiresDialect(PostgreSQLDialect.class) +@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class) public class PostgreSQLInetTypesOtherContributorTest extends PostgreSQLInetTypesOtherTest { @Override diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherTest.java index c341da980dfc..e02103aefff9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/usertype/inet/PostgreSQLInetTypesOtherTest.java @@ -9,13 +9,13 @@ import org.hibernate.boot.spi.MetadataBuilderContributor; import org.hibernate.boot.spi.MetadataBuilderImplementor; -import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.query.NativeQuery; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.type.spi.TypeConfiguration; -import org.hibernate.testing.RequiresDialect; import org.junit.Test; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; @@ -24,7 +24,7 @@ /** * @author Vlad Mihalcea */ -@RequiresDialect(PostgreSQLDialect.class) +@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class) public class PostgreSQLInetTypesOtherTest extends BaseEntityManagerFunctionalTestCase { @Override diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLFunctionProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLFunctionProcedureTest.java index c2300fec9aaa..e3c796cadf46 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLFunctionProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLFunctionProcedureTest.java @@ -7,7 +7,6 @@ import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; import java.sql.Timestamp; import java.sql.Types; import java.time.LocalDateTime; @@ -234,34 +233,6 @@ public void testFunctionWithJDBC() { } ); } - @Test - public void testFunctionWithJDBCByName() { - doInJPA( this::entityManagerFactory, entityManager -> { - try { - Session session = entityManager.unwrap( Session.class ); - Long phoneCount = session.doReturningWork( connection -> { - CallableStatement function = null; - try { - function = connection.prepareCall( "{ ? = call fn_count_phones(?) }" ); - function.registerOutParameter( "phoneCount", Types.BIGINT ); - function.setLong( "personId", 1L ); - function.execute(); - return function.getLong( 1 ); - } - finally { - if ( function != null ) { - function.close(); - } - } - } ); - assertEquals( Long.valueOf( 2 ), phoneCount ); - } - catch (Exception e) { - assertEquals( SQLFeatureNotSupportedException.class, e.getCause().getClass() ); - } - } ); - } - @Test @JiraKey(value = "HHH-11863") public void testSysRefCursorAsOutParameter() { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLStoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLStoredProcedureTest.java index dd3dd31b1384..60befa8191cf 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLStoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/procedure/PostgreSQLStoredProcedureTest.java @@ -7,7 +7,6 @@ import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; import java.sql.Timestamp; import java.sql.Types; @@ -118,34 +117,6 @@ public void testStoredProcedureWithJDBC(EntityManagerFactoryScope scope) { } ); } - @Test - public void testProcedureWithJDBCByName(EntityManagerFactoryScope scope) { - scope.inTransaction( entityManager -> { - try { - Session session = entityManager.unwrap( Session.class ); - Long phoneCount = session.doReturningWork( connection -> { - CallableStatement procedure = null; - try { - procedure = connection.prepareCall( "{ call sp_count_phones(?,?) }" ); - procedure.registerOutParameter( "phoneCount", Types.BIGINT ); - procedure.setLong( "personId", 1L ); - procedure.execute(); - return procedure.getLong( 1 ); - } - finally { - if ( procedure != null ) { - procedure.close(); - } - } - } ); - assertEquals( Long.valueOf( 2 ), phoneCount ); - } - catch (Exception e) { - assertEquals( SQLFeatureNotSupportedException.class, e.getCause().getClass() ); - } - } ); - } - @Test @JiraKey("HHH-11863") @RequiresDialect(value = PostgreSQLDialect.class, majorVersion = 14, comment = "Stored procedure OUT parameters are only supported since version 14") diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/type/PostgresIntervalSecondTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/type/PostgresIntervalSecondTest.java index 693b5ff215a3..9e5a1b08e2cf 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/type/PostgresIntervalSecondTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/type/PostgresIntervalSecondTest.java @@ -11,6 +11,7 @@ import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.dialect.type.PostgreSQLCastingIntervalSecondJdbcType; import org.hibernate.dialect.type.PostgreSQLIntervalSecondJdbcType; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.persister.entity.EntityPersister; @@ -59,7 +60,7 @@ public void verifyMappings(SessionFactoryScope scope) { assertThat( durationJdbcType ).isEqualTo( NumericJdbcType.INSTANCE ); final JdbcType intervalType = jdbcTypeRegistry.getDescriptor( SqlTypes.INTERVAL_SECOND ); - assertThat( intervalType ).isOfAnyClassIn( PostgreSQLIntervalSecondJdbcType.class ); + assertThat( intervalType ).isOfAnyClassIn( PostgreSQLIntervalSecondJdbcType.class, PostgreSQLCastingIntervalSecondJdbcType.class ); // a simple duration field with no overrides - so should be using a default JdbcType assertThat( entityDescriptor.findAttributeMapping( "duration" ) diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java index 7a919b812158..3014a4419a60 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java @@ -173,6 +173,49 @@ else if ( "org.postgresql.Driver".equals( config.driverClassName ) ) { } } ); } + else if ( "com.edb.Driver".equals( config.driverClassName ) ) { + validateConnections( c -> { + // Until pgjdbc provides a method for this out of the box, we have to do this manually + // See https://github.com/pgjdbc/pgjdbc/issues/3049 + try { + final Class pgConnection = Class.forName( "com.edb.jdbc.PgConnection" ); + final Object connection = c.unwrap( pgConnection ); + final Object typeInfo = pgConnection.getMethod( "getTypeInfo" ).invoke( connection ); + final Class typeInfoCacheClass = Class.forName( "com.edb.jdbc.TypeInfoCache" ); + final Field oidToPgNameField = typeInfoCacheClass.getDeclaredField( "oidToPgName" ); + final Field pgNameToOidField = typeInfoCacheClass.getDeclaredField( "pgNameToOid" ); + final Field pgNameToSQLTypeField = typeInfoCacheClass.getDeclaredField( "pgNameToSQLType" ); + final Field oidToSQLTypeField = typeInfoCacheClass.getDeclaredField( "oidToSQLType" ); + oidToPgNameField.setAccessible( true ); + pgNameToOidField.setAccessible( true ); + pgNameToSQLTypeField.setAccessible( true ); + oidToSQLTypeField.setAccessible( true ); + //noinspection unchecked + final Map oidToPgName = (Map) oidToPgNameField.get( typeInfo ); + //noinspection unchecked + final Map pgNameToOid = (Map) pgNameToOidField.get( typeInfo ); + //noinspection unchecked + final Map pgNameToSQLType = (Map) pgNameToSQLTypeField.get( typeInfo ); + //noinspection unchecked + final Map oidToSQLType = (Map) oidToSQLTypeField.get( typeInfo ); + for ( Iterator> iter = pgNameToOid.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry entry = iter.next(); + final String typeName = entry.getKey(); + if ( !PGJDBC_STANDARD_TYPE_NAMES.contains( typeName ) ) { + final Integer oid = entry.getValue(); + oidToPgName.remove( oid ); + oidToSQLType.remove( oid ); + pgNameToSQLType.remove( typeName ); + iter.remove(); + } + } + return true; + } + catch (Exception e) { + throw new RuntimeException( e ); + } + } ); + } } public void onDefaultTimeZoneChange() { diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/CustomRunner.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/CustomRunner.java index 866a92cc02ed..c37b18dae8be 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/CustomRunner.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/CustomRunner.java @@ -11,6 +11,7 @@ import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import org.hibernate.dialect.Dialect; import org.hibernate.internal.util.StringHelper; @@ -25,7 +26,9 @@ import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.SkipForDialects; import org.hibernate.testing.orm.junit.DialectContext; +import org.hibernate.testing.orm.junit.DialectFeatureCheck; import org.hibernate.testing.orm.junit.DialectFilterExtension; +import org.hibernate.testing.orm.junit.RequiresDialectFeatureGroup; import org.hibernate.testing.orm.junit.SkipForDialectGroup; import org.junit.BeforeClass; import org.junit.Ignore; @@ -442,6 +445,30 @@ protected Ignore convertSkipToIgnore(FrameworkMethod frameworkMethod) { } } + Collection effectiveRequiresDialectFeatures = Helper.collectAnnotations( + org.hibernate.testing.orm.junit.RequiresDialectFeature.class, + RequiresDialectFeatureGroup.class, + frameworkMethod, + getTestClass() + ); + + for ( org.hibernate.testing.orm.junit.RequiresDialectFeature effectiveRequiresDialectFeature : effectiveRequiresDialectFeatures ) { + try { + final Class featureClass = effectiveRequiresDialectFeature.feature(); + final DialectFeatureCheck featureCheck = featureClass.getConstructor().newInstance(); + boolean testResult = featureCheck.apply( dialect ); + if ( effectiveRequiresDialectFeature.reverse() ) { + testResult = !testResult; + } + if ( !testResult ) { + return buildIgnore( effectiveRequiresDialectFeature ); + } + } + catch (ReflectiveOperationException e) { + throw new RuntimeException( "Unable to instantiate DialectFeatureCheck class", e ); + } + } + return null; } @@ -567,6 +594,14 @@ private Ignore buildIgnore(RequiresDialectFeature requiresDialectFeature) { ); } + private Ignore buildIgnore(org.hibernate.testing.orm.junit.RequiresDialectFeature requiresDialectFeature) { + return buildIgnore( + String.format( Locale.ROOT, "Failed @RequiresDialectFeature [%s]", requiresDialectFeature.feature() ), + requiresDialectFeature.comment(), + requiresDialectFeature.jiraKey() + ); + } + private boolean isMatch(Class condition) { try { Skip.Matcher matcher = condition.newInstance(); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java index ea7a8b5a0f7a..38d4c60c9329 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java @@ -55,6 +55,7 @@ import org.hibernate.dialect.NationalizationSupport; import org.hibernate.dialect.OracleDialect; import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.dialect.PostgreSQLDriverKind; import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SpannerDialect; import org.hibernate.dialect.SybaseASEDialect; @@ -970,6 +971,12 @@ public boolean apply(Dialect dialect) { } } + public static class IsPgJdbc implements DialectFeatureCheck { + public boolean apply(Dialect dialect) { + return dialect instanceof PostgreSQLDialect && ( (PostgreSQLDialect) dialect ).getDriverKind() == PostgreSQLDriverKind.PG_JDBC; + } + } + public static class SupportsCommentOn implements DialectFeatureCheck { public boolean apply(Dialect dialect) { return dialect.supportsCommentOn(); diff --git a/local-build-plugins/src/main/groovy/local.databases.gradle b/local-build-plugins/src/main/groovy/local.databases.gradle index 150ec7f19236..4156a32b27d6 100644 --- a/local-build-plugins/src/main/groovy/local.databases.gradle +++ b/local-build-plugins/src/main/groovy/local.databases.gradle @@ -77,13 +77,13 @@ ext { ], edb_ci : [ 'db.dialect' : 'org.hibernate.dialect.PostgresPlusDialect', - 'jdbc.driver': 'org.postgresql.Driver', + 'jdbc.driver': 'com.edb.Driver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com - 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test?preparedStatementCacheQueries=0&escapeSyntaxCallMode=callIfNoReturn', - 'jdbc.datasource' : 'org.postgresql.Driver', -// 'jdbc.datasource' : 'org.postgresql.ds.PGSimpleDataSource', + 'jdbc.url' : 'jdbc:edb://' + dbHost + '/hibernate_orm_test?preparedStatementCacheQueries=0&escapeSyntaxCallMode=callIfNoReturn', + 'jdbc.datasource' : 'com.edb.Driver', +// 'jdbc.datasource' : 'com.edb.ds.PGSimpleDataSource', 'connection.init_sql' : '' ], sybase_ci : [ diff --git a/local-build-plugins/src/main/groovy/local.java-module.gradle b/local-build-plugins/src/main/groovy/local.java-module.gradle index 40499736c718..f6a909bc4178 100644 --- a/local-build-plugins/src/main/groovy/local.java-module.gradle +++ b/local-build-plugins/src/main/groovy/local.java-module.gradle @@ -70,6 +70,7 @@ dependencies { testRuntimeOnly jdbcLibs.derbyTools testRuntimeOnly jdbcLibs.hsqldb testRuntimeOnly jdbcLibs.postgresql + testRuntimeOnly jdbcLibs.edb testRuntimeOnly jdbcLibs.mssql testRuntimeOnly jdbcLibs.informix testRuntimeOnly jdbcLibs.cockroachdb diff --git a/settings.gradle b/settings.gradle index 90b3c1818675..0c7993dca334 100644 --- a/settings.gradle +++ b/settings.gradle @@ -227,6 +227,7 @@ dependencyResolutionManagement { def mysqlVersion = version "mysql", "9.2.0" def oracleVersion = version "oracle", "23.7.0.25.01" def pgsqlVersion = version "pgsql", "42.7.4" + def edbVersion = version "edb", "42.7.3.3" def sybaseVersion = version "sybase", "1.3.1" def tidbVersion = version "tidb", mysqlVersion def altibaseVersion = version "altibase", "7.3.0.0.3" @@ -238,6 +239,7 @@ dependencyResolutionManagement { library( "derbyTools", "org.apache.derby", "derbytools" ).versionRef( derbyVersion ) library( "postgresql", "org.postgresql", "postgresql" ).versionRef( pgsqlVersion ) library( "cockroachdb", "org.postgresql", "postgresql" ).versionRef( pgsqlVersion ) + library( "edb", "com.enterprisedb", "edb-jdbc" ).versionRef( edbVersion ) library( "mysql", "com.mysql", "mysql-connector-j" ).versionRef( mysqlVersion ) library( "tidb", "com.mysql", "mysql-connector-j" ).versionRef( tidbVersion ) library( "mariadb", "org.mariadb.jdbc", "mariadb-java-client" ).versionRef( mariadbVersion )