From add62a188bea67cf5589a2a2d48aa5ca2ca7890c Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Fri, 12 Apr 2024 16:40:04 +0200 Subject: [PATCH] Fix SybaseASEDialect column lenght resolution --- .../community/dialect/MySQLLegacyDialect.java | 17 ++++++++++++++++ .../dialect/SybaseASELegacyDialect.java | 19 ------------------ .../dialect/SybaseLegacyDialect.java | 17 ++++++++++++++++ .../java/org/hibernate/dialect/Dialect.java | 9 +-------- .../org/hibernate/dialect/MySQLDialect.java | 17 ++++++++++++++++ .../hibernate/dialect/SybaseASEDialect.java | 16 --------------- .../org/hibernate/dialect/SybaseDialect.java | 17 ++++++++++++++++ ...tionExtractorJdbcDatabaseMetaDataImpl.java | 20 +++++++++++++++---- 8 files changed, 85 insertions(+), 47 deletions(-) diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java index 8d391fa066..ba551f5464 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java @@ -508,6 +508,23 @@ public class MySQLLegacyDialect extends Dialect { ); } + @Override + public int resolveSqlTypeLength( + String columnTypeName, + int jdbcTypeCode, + int precision, + int scale, + int displaySize) { + // It seems MariaDB/MySQL return the precision in bytes depending on the charset, + // so to detect whether we have a single character here, we check the display size + if ( jdbcTypeCode == Types.CHAR && precision <= 4 ) { + return displaySize; + } + else { + return precision; + } + } + @Override public int getPreferredSqlTypeCodeForBoolean() { return Types.BIT; diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java index 117707f830..230b6d4f1e 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java @@ -10,7 +10,6 @@ import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import java.util.Map; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -18,7 +17,6 @@ import org.hibernate.QueryTimeoutException; import org.hibernate.boot.model.TypeContributions; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.RowLockStrategy; import org.hibernate.dialect.SybaseDriverKind; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.dialect.pagination.TopLimitHandler; @@ -34,7 +32,6 @@ import org.hibernate.internal.util.JdbcExceptionHelper; import org.hibernate.query.sqm.IntervalType; import org.hibernate.query.sqm.TemporalUnit; import org.hibernate.service.ServiceRegistry; -import org.hibernate.sql.ForUpdateFragment; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -238,22 +235,6 @@ public class SybaseASELegacyDialect extends SybaseLegacyDialect { } } - @Override - public int resolveSqlTypeLength( - String columnTypeName, - int jdbcTypeCode, - int precision, - int scale, - int displaySize) { - // Sybase ASE reports the "actual" precision in the display size - switch ( jdbcTypeCode ) { - case Types.REAL: - case Types.DOUBLE: - return displaySize; - } - return super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize ); - } - @Override public String currentDate() { return "current_date()"; diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java index 2dd133a9a2..25e81009d1 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java @@ -158,6 +158,23 @@ public class SybaseLegacyDialect extends AbstractTransactSQLDialect { ); } + @Override + public int resolveSqlTypeLength( + String columnTypeName, + int jdbcTypeCode, + int precision, + int scale, + int displaySize) { + // Sybase jconnect driver reports the "actual" precision in the display size + switch ( jdbcTypeCode ) { + case Types.VARCHAR: + case Types.REAL: + case Types.DOUBLE: + return displaySize; + } + return super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize ); + } + @Override public SqmTranslatorFactory getSqmTranslatorFactory() { return new StandardSqmTranslatorFactory() { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 9f7db4e42e..0324510385 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -764,14 +764,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun int precision, int scale, int displaySize) { - // It seems MariaDB/MySQL return the precision in bytes depending on the charset, - // so to detect whether we have a single character here, we check the display size - if ( jdbcTypeCode == Types.CHAR && precision <= 4 ) { - return displaySize; - } - else { - return precision; - } + return precision; } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index b3ea382378..c51edef707 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -544,6 +544,23 @@ public class MySQLDialect extends Dialect { ); } + @Override + public int resolveSqlTypeLength( + String columnTypeName, + int jdbcTypeCode, + int precision, + int scale, + int displaySize) { + // It seems MariaDB/MySQL return the precision in bytes depending on the charset, + // so to detect whether we have a single character here, we check the display size + if ( jdbcTypeCode == Types.CHAR && precision <= 4 ) { + return displaySize; + } + else { + return precision; + } + } + @Override public int getPreferredSqlTypeCodeForBoolean() { return Types.BIT; 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 80e9b0c0b5..001c0499b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java @@ -252,22 +252,6 @@ public class SybaseASEDialect extends SybaseDialect { } } - @Override - public int resolveSqlTypeLength( - String columnTypeName, - int jdbcTypeCode, - int precision, - int scale, - int displaySize) { - // Sybase ASE reports the "actual" precision in the display size - switch ( jdbcTypeCode ) { - case Types.REAL: - case Types.DOUBLE: - return displaySize; - } - return super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize ); - } - @Override public String currentDate() { return "current_date()"; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java index 81ae3d24ee..a6063b8583 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java @@ -140,6 +140,23 @@ public class SybaseDialect extends AbstractTransactSQLDialect { ); } + @Override + public int resolveSqlTypeLength( + String columnTypeName, + int jdbcTypeCode, + int precision, + int scale, + int displaySize) { + // Sybase jconnect driver reports the "actual" precision in the display size + switch ( jdbcTypeCode ) { + case Types.VARCHAR: + case Types.REAL: + case Types.DOUBLE: + return displaySize; + } + return super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize ); + } + @Override public SqmTranslatorFactory getSqmTranslatorFactory() { return new StandardSqmTranslatorFactory() { diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java index 6273d462da..1c33291926 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java @@ -13,6 +13,7 @@ import java.util.StringTokenizer; import org.hibernate.boot.model.naming.DatabaseIdentifier; import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.dialect.Dialect; import org.hibernate.tool.schema.extract.spi.ExtractionContext; import org.hibernate.tool.schema.extract.spi.TableInformation; @@ -134,6 +135,8 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform } protected void addColumns(TableInformation tableInformation) { + final Dialect dialect = getExtractionContext().getJdbcEnvironment().getDialect(); + final ExtractionContext extractionContext = getExtractionContext(); // We use this dummy query to retrieve the table information through the ResultSetMetaData // This is significantly better than to use the DatabaseMetaData especially on Oracle with synonyms enabled @@ -153,13 +156,22 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform for ( int i = 1; i <= columnCount; i++ ) { final String columnName = metaData.getColumnName( i ); + final int columnType = metaData.getColumnType( i ); + final String typeName = new StringTokenizer( metaData.getColumnTypeName( i ), "()" ).nextToken(); + final int scale = metaData.getScale( i ); final ColumnInformationImpl columnInformation = new ColumnInformationImpl( tableInformation, DatabaseIdentifier.toIdentifier( columnName ), - metaData.getColumnType( i ), - new StringTokenizer( metaData.getColumnTypeName( i ), "()" ).nextToken(), - metaData.getPrecision( i ), - metaData.getScale( i ), + columnType, + typeName, + dialect.resolveSqlTypeLength( + typeName, + columnType, + metaData.getPrecision( i ), + scale, + metaData.getColumnDisplaySize( i ) + ), + scale, interpretNullable( metaData.isNullable( i ) ) ); tableInformation.addColumn( columnInformation );