From 304a0a89daaf7b1e3cab31cdc7c6c03c927228cb Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Mon, 20 Nov 2017 16:21:10 +0800 Subject: [PATCH] HHH-12120 - Update StandardDialectResolver to reflect the latest Dialects of PostgreSQL and MySQL --- .../java/org/hibernate/dialect/Database.java | 539 ++++++++++++++++++ .../internal/StandardDialectResolver.java | 200 +------ .../dialect/resolver/DialectFactoryTest.java | 19 +- 3 files changed, 562 insertions(+), 196 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/dialect/Database.java diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Database.java b/hibernate-core/src/main/java/org/hibernate/dialect/Database.java new file mode 100644 index 0000000000..7b304f6f28 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Database.java @@ -0,0 +1,539 @@ +package org.hibernate.dialect; + +import org.hibernate.HibernateException; +import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; + +/** + * List all supported relational database systems. + * + * @author Vlad Mihalcea + */ +public enum Database { + + CACHE { + @Override + public Class latestDialect() { + return Cache71Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + CUBRID { + @Override + public Class latestDialect() { + return CUBRIDDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "CUBRID".equalsIgnoreCase( databaseName ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + DB2 { + @Override + public Class latestDialect() { + return DB2400Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "DB2 UDB for AS/400".equals( databaseName ) ) { + return new DB2400Dialect(); + } + + if ( databaseName.startsWith( "DB2/" ) ) { + return new DB2Dialect(); + } + + return null; + } + }, + DERBY { + @Override + public Class latestDialect() { + return DerbyTenSevenDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "Apache Derby".equals( databaseName ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + final int minorVersion = info.getDatabaseMinorVersion(); + + if ( majorVersion > 10 || ( majorVersion == 10 && minorVersion >= 7 ) ) { + return latestDialectInstance( this ); + } + else if ( majorVersion == 10 && minorVersion == 6 ) { + return new DerbyTenSixDialect(); + } + else if ( majorVersion == 10 && minorVersion == 5 ) { + return new DerbyTenFiveDialect(); + } + else { + return new DerbyDialect(); + } + } + + return null; + } + }, + ENTERPRISEDB { + @Override + public Class latestDialect() { + return PostgresPlusDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "EnterpriseDB".equals( databaseName ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + FIREBIRD { + @Override + public Class latestDialect() { + return FirebirdDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( databaseName.startsWith( "Firebird" ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + FRONTBASE { + @Override + public Class latestDialect() { + return FrontBaseDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + H2 { + @Override + public Class latestDialect() { + return H2Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "H2".equals( databaseName ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + HANA { + @Override + public Class latestDialect() { + return HANAColumnStoreDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "HDB".equals( databaseName ) ) { + // SAP recommends defaulting to column store. + return latestDialectInstance( this ); + } + + return null; + } + }, + HSQL { + @Override + public Class latestDialect() { + return HSQLDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "HSQL Database Engine".equals( databaseName ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + INFORMIX { + @Override + public Class latestDialect() { + return Informix10Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "Informix Dynamic Server".equals( databaseName ) ) { + return latestDialectInstance( this ); + } + + return null; + } + }, + INGRES { + @Override + public Class latestDialect() { + return Ingres10Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "ingres".equalsIgnoreCase( databaseName ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + final int minorVersion = info.getDatabaseMinorVersion(); + + if ( majorVersion < 9 ) { + return new IngresDialect(); + } + else if ( majorVersion == 9 ) { + if ( minorVersion > 2 ) { + return new Ingres9Dialect(); + } + return new IngresDialect(); + } + else if ( majorVersion == 10 ) { + return new Ingres10Dialect(); + } + + return latestDialectInstance( this ); + } + + return null; + } + }, + INTERBASE { + @Override + public Class latestDialect() { + return InterbaseDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + MARIADB { + @Override + public Class latestDialect() { + return MariaDB53Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + + if ( info.getDriverName() != null && info.getDriverName().startsWith( "MariaDB" ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + final int minorVersion = info.getDatabaseMinorVersion(); + + if ( majorVersion < 5 || ( majorVersion == 5 && minorVersion < 3 ) ) { + return new MariaDBDialect(); + } + + return latestDialectInstance( this ); + } + + return null; + } + }, + MAXDB { + @Override + public Class latestDialect() { + return SAPDBDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + MCKOI { + @Override + public Class latestDialect() { + return MckoiDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + MIMERSQL { + @Override + public Class latestDialect() { + return MimerSQLDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + MYSQL { + @Override + public Class latestDialect() { + return MySQL57Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "MySQL".equals( databaseName ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + final int minorVersion = info.getDatabaseMinorVersion(); + + if ( majorVersion < 5 ) { + return new MySQLDialect(); + } + else if ( majorVersion == 5 ) { + if ( minorVersion < 5 ) { + return new MySQL5Dialect(); + } + else if ( minorVersion < 7 ) { + return new MySQL55Dialect(); + } + else { + return new MySQL57Dialect(); + } + } + + return latestDialectInstance( this ); + } + + return null; + } + }, + ORACLE { + @Override + public Class latestDialect() { + return Oracle12cDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "Oracle".equals( databaseName ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + + switch ( majorVersion ) { + case 12: + return new Oracle12cDialect(); + case 11: + // fall through + case 10: + return new Oracle10gDialect(); + case 9: + return new Oracle9iDialect(); + case 8: + return new Oracle8iDialect(); + default: + latestDialectInstance( this ); + + } + } + + return null; + } + }, + POINTBASE { + @Override + public Class latestDialect() { + return PointbaseDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + POSTGRESQL { + @Override + public Class latestDialect() { + return PostgreSQL95Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "PostgreSQL".equals( databaseName ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + final int minorVersion = info.getDatabaseMinorVersion(); + + if ( majorVersion < 8 ) { + return new PostgreSQL81Dialect(); + } + + if ( majorVersion == 8 ) { + return minorVersion >= 2 ? new PostgreSQL82Dialect() : new PostgreSQL81Dialect(); + } + + if ( majorVersion == 9 ) { + if ( minorVersion < 2 ) { + return new PostgreSQL9Dialect(); + } + else if ( minorVersion < 4 ) { + return new PostgreSQL92Dialect(); + } + else if ( minorVersion < 5 ) { + return new PostgreSQL94Dialect(); + } + else if ( minorVersion < 6 ) { + return new PostgreSQL95Dialect(); + } + } + + return latestDialectInstance( this ); + } + + return null; + } + }, + PROGRESS { + @Override + public Class latestDialect() { + return ProgressDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + SQLSERVER { + @Override + public Class latestDialect() { + return SQLServer2012Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( databaseName.startsWith( "Microsoft SQL Server" ) ) { + final int majorVersion = info.getDatabaseMajorVersion(); + + switch ( majorVersion ) { + case 8: { + return new SQLServerDialect(); + } + case 9: { + return new SQLServer2005Dialect(); + } + case 10: { + return new SQLServer2008Dialect(); + } + case 11: + case 12: + case 13: { + return new SQLServer2012Dialect(); + } + default: { + if ( majorVersion < 8 ) { + return new SQLServerDialect(); + } + else { + // assume `majorVersion > 13` + return latestDialectInstance( this ); + } + } + } + } + + return null; + } + }, + SYBASE { + @Override + public Class latestDialect() { + return SybaseASE15Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + final String databaseName = info.getDatabaseName(); + + if ( "Sybase SQL Server".equals( databaseName ) || "Adaptive Server Enterprise".equals( databaseName ) ) { + return latestDialectInstance( this ); + } + + if ( databaseName.startsWith( "Adaptive Server Anywhere" ) ) { + return new SybaseAnywhereDialect(); + } + + return null; + } + }, + TERADATA { + @Override + public Class latestDialect() { + return Teradata14Dialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }, + TIMESTEN { + @Override + public Class latestDialect() { + return TimesTenDialect.class; + } + + @Override + public Dialect resolveDialect(DialectResolutionInfo info) { + return null; + } + }; + + public abstract Class latestDialect(); + + public abstract Dialect resolveDialect(DialectResolutionInfo info); + + private static Dialect latestDialectInstance(Database database) { + try { + return database.latestDialect().newInstance(); + } + catch (InstantiationException | IllegalAccessException e) { + throw new HibernateException( e ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java index ae838142d2..6168fd5b51 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java @@ -6,40 +6,8 @@ */ package org.hibernate.engine.jdbc.dialect.internal; -import org.hibernate.dialect.CUBRIDDialect; -import org.hibernate.dialect.DB2400Dialect; -import org.hibernate.dialect.DB2Dialect; -import org.hibernate.dialect.DerbyDialect; -import org.hibernate.dialect.DerbyTenFiveDialect; -import org.hibernate.dialect.DerbyTenSevenDialect; -import org.hibernate.dialect.DerbyTenSixDialect; +import org.hibernate.dialect.Database; import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.FirebirdDialect; -import org.hibernate.dialect.H2Dialect; -import org.hibernate.dialect.HANAColumnStoreDialect; -import org.hibernate.dialect.HSQLDialect; -import org.hibernate.dialect.InformixDialect; -import org.hibernate.dialect.Ingres10Dialect; -import org.hibernate.dialect.Ingres9Dialect; -import org.hibernate.dialect.IngresDialect; -import org.hibernate.dialect.MySQL5Dialect; -import org.hibernate.dialect.MySQLDialect; -import org.hibernate.dialect.Oracle10gDialect; -import org.hibernate.dialect.Oracle12cDialect; -import org.hibernate.dialect.Oracle8iDialect; -import org.hibernate.dialect.Oracle9iDialect; -import org.hibernate.dialect.PostgreSQL81Dialect; -import org.hibernate.dialect.PostgreSQL82Dialect; -import org.hibernate.dialect.PostgreSQL92Dialect; -import org.hibernate.dialect.PostgreSQL94Dialect; -import org.hibernate.dialect.PostgreSQL9Dialect; -import org.hibernate.dialect.PostgresPlusDialect; -import org.hibernate.dialect.SQLServer2005Dialect; -import org.hibernate.dialect.SQLServer2008Dialect; -import org.hibernate.dialect.SQLServer2012Dialect; -import org.hibernate.dialect.SQLServerDialect; -import org.hibernate.dialect.SybaseASE15Dialect; -import org.hibernate.dialect.SybaseAnywhereDialect; import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; import org.hibernate.engine.jdbc.dialect.spi.DialectResolver; import org.hibernate.internal.CoreLogging; @@ -60,170 +28,12 @@ public class StandardDialectResolver implements DialectResolver { @Override public Dialect resolveDialect(DialectResolutionInfo info) { - final String databaseName = info.getDatabaseName(); - if ( "CUBRID".equalsIgnoreCase( databaseName ) ) { - return new CUBRIDDialect(); - } - - if ( "HSQL Database Engine".equals( databaseName ) ) { - return new HSQLDialect(); - } - - if ( "H2".equals( databaseName ) ) { - return new H2Dialect(); - } - - if ( "MySQL".equals( databaseName ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - - if (majorVersion >= 5 ) { - return new MySQL5Dialect(); + for ( Database database : Database.values() ) { + Dialect dialect = database.resolveDialect( info ); + if ( dialect != null ) { + return dialect; } - - return new MySQLDialect(); - } - - if ( "PostgreSQL".equals( databaseName ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - final int minorVersion = info.getDatabaseMinorVersion(); - - if ( majorVersion == 9 ) { - if ( minorVersion >= 4 ) { - return new PostgreSQL94Dialect(); - } - else if ( minorVersion >= 2 ) { - return new PostgreSQL92Dialect(); - } - return new PostgreSQL9Dialect(); - } - - if ( majorVersion == 8 && minorVersion >= 2 ) { - return new PostgreSQL82Dialect(); - } - - return new PostgreSQL81Dialect(); - } - - if ( "EnterpriseDB".equals( databaseName ) ) { - return new PostgresPlusDialect(); - } - - if ( "Apache Derby".equals( databaseName ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - final int minorVersion = info.getDatabaseMinorVersion(); - - if ( majorVersion > 10 || ( majorVersion == 10 && minorVersion >= 7 ) ) { - return new DerbyTenSevenDialect(); - } - else if ( majorVersion == 10 && minorVersion == 6 ) { - return new DerbyTenSixDialect(); - } - else if ( majorVersion == 10 && minorVersion == 5 ) { - return new DerbyTenFiveDialect(); - } - else { - return new DerbyDialect(); - } - } - - if ( "ingres".equalsIgnoreCase( databaseName ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - final int minorVersion = info.getDatabaseMinorVersion(); - - switch ( majorVersion ) { - case 9: - if (minorVersion > 2) { - return new Ingres9Dialect(); - } - return new IngresDialect(); - case 10: - return new Ingres10Dialect(); - default: - LOG.unknownIngresVersion( majorVersion ); - } - return new IngresDialect(); - } - - if ( databaseName.startsWith( "Microsoft SQL Server" ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - - switch ( majorVersion ) { - case 8: { - return new SQLServerDialect(); - } - case 9: { - return new SQLServer2005Dialect(); - } - case 10: { - return new SQLServer2008Dialect(); - } - case 11: - case 12: - case 13: { - return new SQLServer2012Dialect(); - } - default: { - if ( majorVersion < 8 ) { - LOG.unknownSqlServerVersion( majorVersion, SQLServerDialect.class ); - return new SQLServerDialect(); - } - else { - // assume `majorVersion > 13` - LOG.unknownSqlServerVersion( majorVersion, SQLServer2012Dialect.class ); - return new SQLServer2012Dialect(); - } - } - } - } - - if ( "Sybase SQL Server".equals( databaseName ) || "Adaptive Server Enterprise".equals( databaseName ) ) { - return new SybaseASE15Dialect(); - } - - if ( databaseName.startsWith( "Adaptive Server Anywhere" ) ) { - return new SybaseAnywhereDialect(); - } - - if ( "Informix Dynamic Server".equals( databaseName ) ) { - return new InformixDialect(); - } - - if ( "DB2 UDB for AS/400".equals( databaseName ) ) { - return new DB2400Dialect(); - } - - if ( databaseName.startsWith( "DB2/" ) ) { - return new DB2Dialect(); - } - - if ( "Oracle".equals( databaseName ) ) { - final int majorVersion = info.getDatabaseMajorVersion(); - - switch ( majorVersion ) { - case 12: - return new Oracle12cDialect(); - case 11: - // fall through - case 10: - return new Oracle10gDialect(); - case 9: - return new Oracle9iDialect(); - case 8: - return new Oracle8iDialect(); - default: - LOG.unknownOracleVersion( majorVersion ); - } - return new Oracle8iDialect(); - } - - if ( "HDB".equals( databaseName ) ) { - // SAP recommends defaulting to column store. - return new HANAColumnStoreDialect(); - } - - if ( databaseName.startsWith( "Firebird" ) ) { - return new FirebirdDialect(); } return null; diff --git a/hibernate-core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java b/hibernate-core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java index 8856cf4f9f..3ccdc415cd 100644 --- a/hibernate-core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java @@ -27,8 +27,11 @@ import org.hibernate.dialect.DerbyTenSixDialect; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.H2Dialect; import org.hibernate.dialect.HSQLDialect; +import org.hibernate.dialect.Informix10Dialect; import org.hibernate.dialect.InformixDialect; import org.hibernate.dialect.IngresDialect; +import org.hibernate.dialect.MySQL55Dialect; +import org.hibernate.dialect.MySQL57Dialect; import org.hibernate.dialect.MySQL5Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.Oracle10gDialect; @@ -36,6 +39,9 @@ import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.dialect.Oracle9iDialect; import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.dialect.PostgreSQL82Dialect; +import org.hibernate.dialect.PostgreSQL92Dialect; +import org.hibernate.dialect.PostgreSQL94Dialect; +import org.hibernate.dialect.PostgreSQL95Dialect; import org.hibernate.dialect.PostgreSQL9Dialect; import org.hibernate.dialect.PostgresPlusDialect; import org.hibernate.dialect.SQLServerDialect; @@ -136,9 +142,20 @@ public class DialectFactoryTest extends BaseUnitTestCase { testDetermination( "H2", H2Dialect.class, resolver ); testDetermination( "MySQL", MySQLDialect.class, resolver ); testDetermination( "MySQL", 5, 0, MySQL5Dialect.class, resolver ); + testDetermination( "MySQL", 5, 5, MySQL55Dialect.class, resolver ); + testDetermination( "MySQL", 5, 6, MySQL55Dialect.class, resolver ); + testDetermination( "MySQL", 5, 7, MySQL57Dialect.class, resolver ); + testDetermination( "MySQL", 8, 0, MySQL57Dialect.class, resolver ); testDetermination( "PostgreSQL", PostgreSQL81Dialect.class, resolver ); testDetermination( "PostgreSQL", 8, 2, PostgreSQL82Dialect.class, resolver ); + testDetermination( "PostgreSQL", 8, 3, PostgreSQL82Dialect.class, resolver ); testDetermination( "PostgreSQL", 9, 0, PostgreSQL9Dialect.class, resolver ); + testDetermination( "PostgreSQL", 9, 1, PostgreSQL9Dialect.class, resolver ); + testDetermination( "PostgreSQL", 9, 2, PostgreSQL92Dialect.class, resolver ); + testDetermination( "PostgreSQL", 9, 3, PostgreSQL92Dialect.class, resolver ); + testDetermination( "PostgreSQL", 9, 4, PostgreSQL94Dialect.class, resolver ); + testDetermination( "PostgreSQL", 9, 5, PostgreSQL95Dialect.class, resolver ); + testDetermination( "PostgreSQL", 10, 0, PostgreSQL95Dialect.class, resolver ); testDetermination( "EnterpriseDB", 9, 2, PostgresPlusDialect.class, resolver ); testDetermination( "Apache Derby", 10, 4, DerbyDialect.class, resolver ); testDetermination( "Apache Derby", 10, 5, DerbyTenFiveDialect.class, resolver ); @@ -152,7 +169,7 @@ public class DialectFactoryTest extends BaseUnitTestCase { testDetermination( "Sybase SQL Server", SybaseASE15Dialect.class, resolver ); testDetermination( "Adaptive Server Enterprise", SybaseASE15Dialect.class, resolver ); testDetermination( "Adaptive Server Anywhere", SybaseAnywhereDialect.class, resolver ); - testDetermination( "Informix Dynamic Server", InformixDialect.class, resolver ); + testDetermination( "Informix Dynamic Server", Informix10Dialect.class, resolver ); testDetermination( "DB2/NT", DB2Dialect.class, resolver ); testDetermination( "DB2/LINUX", DB2Dialect.class, resolver ); testDetermination( "DB2/6000", DB2Dialect.class, resolver );