From 11139c288a49304439a10365f19955a3669d732a Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 22 Nov 2024 22:36:45 +0100 Subject: [PATCH] HHH-13969 query the page size on Sybase ASE --- .../cfg/DialectSpecificSettings.java | 7 ++ .../hibernate/dialect/SybaseASEDialect.java | 64 +++++++++++-------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java index 5766304956..aee487e96f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/DialectSpecificSettings.java @@ -43,6 +43,13 @@ public interface DialectSpecificSettings { */ String SYBASE_ANSI_NULL = "hibernate.dialect.sybase.extended_string_size"; + /** + * Specifies the maximum page size on Sybase. + * + * @settingDefault {@value org.hibernate.dialect.SybaseASEDialect#MAX_PAGE_SIZE} + */ + String SYBASE_PAGE_SIZE = "hibernate.dialect.sybase.page_size"; + /** * Specifies the bytes per character to use based on the database's configured * charset. diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java index fd5f89646d..fb89fb4585 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java @@ -29,7 +29,6 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate; 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.query.sqm.IntervalType; import org.hibernate.query.common.TemporalUnit; import org.hibernate.service.ServiceRegistry; @@ -49,7 +48,10 @@ import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; import jakarta.persistence.TemporalType; import static org.hibernate.cfg.DialectSpecificSettings.SYBASE_ANSI_NULL; +import static org.hibernate.cfg.DialectSpecificSettings.SYBASE_PAGE_SIZE; import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate; +import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean; +import static org.hibernate.internal.util.config.ConfigurationHelper.getInt; import static org.hibernate.type.SqlTypes.BOOLEAN; import static org.hibernate.type.SqlTypes.DATE; import static org.hibernate.type.SqlTypes.NCLOB; @@ -65,6 +67,8 @@ public class SybaseASEDialect extends SybaseDialect { private static final DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 16, 0 ); + public static final int MAX_PAGE_SIZE = 16_384; + private final SizeStrategy sizeStrategy = new SizeStrategyImpl() { @Override public Size resolveSize( @@ -95,6 +99,7 @@ public class SybaseASEDialect extends SybaseDialect { }; private final boolean ansiNull; + private final int pageSize; public SybaseASEDialect() { this( MINIMUM_VERSION ); @@ -103,37 +108,29 @@ public class SybaseASEDialect extends SybaseDialect { public SybaseASEDialect(DatabaseVersion version) { super(version); ansiNull = false; + pageSize = MAX_PAGE_SIZE; } public SybaseASEDialect(DialectResolutionInfo info) { super(info); ansiNull = isAnsiNull( info ); + pageSize = pageSize( info ); } @Override protected String columnType(int sqlTypeCode) { - switch ( sqlTypeCode ) { - case BOOLEAN: { - // On Sybase ASE, the 'bit' type cannot be null, - // and cannot have indexes (while we don't use - // tinyint to store signed bytes, we can use it - // to store boolean values) - return "tinyint"; - } - case DATE: { - return "date"; - } - case TIME: { - return "time"; - } - case NCLOB: { - // Sybase uses `unitext` instead of the T-SQL `ntext` type name - return "unitext"; - } - default: { - return super.columnType( sqlTypeCode ); - } - } + return switch ( sqlTypeCode ) { + // On Sybase ASE, the 'bit' type cannot be null, + // and cannot have indexes (while we don't use + // tinyint to store signed bytes, we can use it + // to store boolean values) + case BOOLEAN -> "tinyint"; + case DATE -> "date"; + case TIME -> "time"; + // Sybase uses `unitext` instead of the T-SQL `ntext` type name + case NCLOB -> "unitext"; + default -> super.columnType( sqlTypeCode ); + }; } @Override @@ -175,7 +172,7 @@ public class SybaseASEDialect extends SybaseDialect { // not the individual column length -- anyway, the // largest possible page size is 16k, so that's a // hard upper limit - return 16_384; + return pageSize; } @Override @@ -220,7 +217,24 @@ public class SybaseASEDialect extends SybaseDialect { } } // default to the dialect-specific configuration setting - return ConfigurationHelper.getBoolean( SYBASE_ANSI_NULL, info.getConfigurationValues(), false ); + return getBoolean( SYBASE_ANSI_NULL, info.getConfigurationValues(), false ); + } + + private int pageSize(DialectResolutionInfo info) { + final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata(); + if ( databaseMetaData != null ) { + try (java.sql.Statement s = databaseMetaData.getConnection().createStatement() ) { + final ResultSet rs = s.executeQuery( "SELECT @@maxpagesize" ); + if ( rs.next() ) { + return rs.getInt( 1 ); + } + } + catch (SQLException ex) { + // Ignore + } + } + // default to the dialect-specific configuration setting + return getInt( SYBASE_PAGE_SIZE, info.getConfigurationValues(), MAX_PAGE_SIZE ); } @Override