HHH-16360 fix schema update precision/scale handling

This commit is contained in:
Gavin 2023-05-24 13:49:53 +02:00 committed by Andrea Boriero
parent 1390b8c781
commit 4be2762624
3 changed files with 46 additions and 9 deletions

View File

@ -954,7 +954,7 @@ public class MySQLDialect extends Dialect {
@Override
public String getAlterColumnTypeString(String columnName, String columnType, String columnDefinition) {
// no way to change just the column type, leaving other attributes intact
return "modify column " + columnName + " " + columnDefinition;
return "modify column " + columnName + " " + columnDefinition.trim();
}
@Override

View File

@ -21,6 +21,9 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
import java.util.List;
import static org.hibernate.type.SqlTypes.isNumericOrDecimal;
import static org.hibernate.type.SqlTypes.isStringType;
class ColumnDefinitions {
static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
@ -51,17 +54,30 @@ class ColumnDefinitions {
}
static boolean hasMatchingLength(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
final int actualSize = columnInformation.getColumnSize();
if ( actualSize == 0 ) {
return true;
}
else {
int sqlType = columnInformation.getTypeCode();
if ( isStringType( sqlType ) ) {
final int actualLength = columnInformation.getColumnSize();
final Size size = column.getColumnSize( dialect, metadata );
final Long requiredLength = size.getLength();
return requiredLength == null
|| requiredLength == actualLength;
}
else if ( isNumericOrDecimal( sqlType ) ) {
// Postgres, H2, SQL Server, and MySQL agree on the following:
final int actualPrecision = columnInformation.getColumnSize();
final int actualScale = columnInformation.getDecimalDigits();
final Size size = column.getColumnSize( dialect, metadata );
final Integer requiredPrecision = size.getPrecision();
return requiredLength != null && requiredLength == actualSize
|| requiredPrecision != null && requiredPrecision == actualSize
|| requiredPrecision == null && requiredLength == null;
final Integer requiredScale = size.getScale();
return requiredPrecision == null
|| requiredScale == null
|| requiredScale == actualScale && requiredPrecision == actualPrecision;
}
// I would really love this to be able to change the binary
// precision of a float/double type, but there simply doesn't
// seem to be any good way to implement it
else {
return true;
}
}

View File

@ -548,6 +548,27 @@ public class SqlTypes {
}
}
/**
* Is this a type with a length, that is, is it
* some kind of character string or binary string?
* @param typeCode a JDBC type code from {@link Types}
*/
public static boolean isStringType(int typeCode) {
switch (typeCode) {
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
case Types.NCHAR:
case Types.NVARCHAR:
case Types.LONGNVARCHAR:
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
default:
return false;
}
}
/**
* Does the given JDBC type code represent some sort of
* character string type?