Skip to content

Commit

Permalink
HHH-18463 Add AzureDialect and determine SQL Server version based on …
Browse files Browse the repository at this point in the history
…compatibility level
  • Loading branch information
beikov committed Aug 7, 2024
1 parent 5550c20 commit e54a6e1
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ public interface DialectSpecificSettings {
*/
public static final String COCKROACH_VERSION_STRING = "hibernate.dialect.cockroach.version_string";

/**
* Specifies the compatibility level of the SQL Server database as returned by {@code select compatibility_level from sys.databases}.
* The number has three digits, the first two digits are the major version, the last digit is the minor version.
*/
public static final String SQL_SERVER_COMPATIBILITY_LEVEL = "hibernate.dialect.sqlserver.compatibility_level";

/**
* Specifies the LOB prefetch size. LOBs larger than this value will be read into memory as the HANA JDBC driver closes
* the LOB when the result set is closed.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect;

import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;

/**
* A {@linkplain Dialect SQL dialect} for Azure SQL Server.
*/
public class AzureSQLServerDialect extends SQLServerDialect {

public AzureSQLServerDialect() {
// Azure SQL Server always is the latest version, so default to a high number
super( DatabaseVersion.make( Integer.MAX_VALUE ) );
}

public AzureSQLServerDialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.hibernate.dialect;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.temporal.ChronoField;
Expand Down Expand Up @@ -40,6 +41,7 @@
import org.hibernate.dialect.unique.AlterTableUniqueIndexDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.BasicSQLExceptionConverter;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
Expand All @@ -52,6 +54,7 @@
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.Column;
import org.hibernate.persister.entity.mutation.EntityMutationTarget;
import org.hibernate.procedure.internal.SQLServerCallableStatementSupport;
Expand Down Expand Up @@ -89,6 +92,7 @@

import jakarta.persistence.TemporalType;

import static org.hibernate.cfg.DialectSpecificSettings.SQL_SERVER_COMPATIBILITY_LEVEL;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.query.sqm.TemporalUnit.NANOSECOND;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
Expand Down Expand Up @@ -174,8 +178,36 @@ public SQLServerDialect(DatabaseVersion version) {
}

public SQLServerDialect(DialectResolutionInfo info) {
super(info);
exporter = createSequenceExporter(info);
this( determineDatabaseVersion( info ) );
registerKeywords( info );
}

private static DatabaseVersion determineDatabaseVersion(DialectResolutionInfo info) {
final Integer compatibilityLevel = getCompatibilityLevel( info );
if ( compatibilityLevel != null ) {
final int majorVersion = compatibilityLevel / 10;
final int minorVersion = compatibilityLevel % 10;
return DatabaseVersion.make( majorVersion, minorVersion );
}
return info.makeCopyOrDefault( MINIMUM_VERSION );
}

private static Integer getCompatibilityLevel(DialectResolutionInfo info) {
final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
if ( databaseMetaData != null ) {
try ( java.sql.Statement statement = databaseMetaData.getConnection().createStatement() ) {
final ResultSet rs = statement.executeQuery( "SELECT compatibility_level FROM sys.databases where name = db_name();" );
if ( rs.next() ) {
return rs.getInt( 1 );
}
}
catch (SQLException e) {
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
}
}

// default to the dialect-specific configuration setting
return ConfigurationHelper.getInteger( SQL_SERVER_COMPATIBILITY_LEVEL, info.getConfigurationValues() );
}

private StandardSequenceExporter createSequenceExporter(DatabaseVersion version) {
Expand Down

0 comments on commit e54a6e1

Please sign in to comment.