HHH-16531 be more forgiving in handling of integral types in schema validation/update
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
0f8ef48e7b
commit
4791b41cf5
|
@ -1591,6 +1591,10 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* {@link Types#VARBINARY BINARY} and
|
||||
* {@link Types#LONGVARBINARY LONGVARBINARY} as the same type, since
|
||||
* Hibernate doesn't really differentiate these types.
|
||||
* <p>
|
||||
* On the other hand, integral types are not treated as equivalent,
|
||||
* instead, {@link #isCompatibleIntegralType(int, int)} is responsible
|
||||
* for determining if the types are compatible.
|
||||
*
|
||||
* @param typeCode1 the first column type info
|
||||
* @param typeCode2 the second column type info
|
||||
|
@ -1600,16 +1604,39 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
public boolean equivalentTypes(int typeCode1, int typeCode2) {
|
||||
return typeCode1==typeCode2
|
||||
|| isNumericOrDecimal(typeCode1) && isNumericOrDecimal(typeCode2)
|
||||
// || isIntegral(typeCode1) && isIntegral(typeCode2)
|
||||
|| isFloatOrRealOrDouble(typeCode1) && isFloatOrRealOrDouble(typeCode2)
|
||||
|| isVarcharType(typeCode1) && isVarcharType(typeCode2)
|
||||
|| isVarbinaryType(typeCode1) && isVarbinaryType(typeCode2)
|
||||
|| isCompatibleIntegralType(typeCode1, typeCode2)
|
||||
// HHH-17908: Since the runtime can cope with enum on the DDL side,
|
||||
// but varchar on the ORM expectation side, let's treat the types as equivalent
|
||||
|| isEnumType( typeCode1 ) && isVarcharType( typeCode2 )
|
||||
|| isEnumType(typeCode1) && isVarcharType(typeCode2)
|
||||
|| sameColumnType(typeCode1, typeCode2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tolerate storing {@code short} in {@code INTEGER} or {@code BIGINT}
|
||||
* or {@code int} in {@code BIGINT} for the purposes of schema validation
|
||||
* and migration.
|
||||
*/
|
||||
private boolean isCompatibleIntegralType(int typeCode1, int typeCode2) {
|
||||
switch (typeCode1) {
|
||||
case TINYINT:
|
||||
return typeCode2 == TINYINT
|
||||
|| typeCode2 == SMALLINT
|
||||
|| typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
case SMALLINT:
|
||||
return typeCode2 == SMALLINT
|
||||
|| typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
case INTEGER:
|
||||
return typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean sameColumnType(int typeCode1, int typeCode2) {
|
||||
try {
|
||||
return Objects.equals( columnType(typeCode1), columnType(typeCode2) );
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.type.descriptor.JdbcTypeNameMapper;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
|
||||
import static org.hibernate.tool.schema.internal.ColumnDefinitions.hasMatchingType;
|
||||
|
||||
/**
|
||||
* Base implementation of {@link SchemaValidator}.
|
||||
|
@ -163,7 +164,7 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
|
|||
Metadata metadata,
|
||||
ExecutionOptions options,
|
||||
Dialect dialect) {
|
||||
if ( !ColumnDefinitions.hasMatchingType( column, columnInformation, metadata, dialect ) ) {
|
||||
if ( !hasMatchingType( column, columnInformation, metadata, dialect ) ) {
|
||||
throw new SchemaManagementException(
|
||||
String.format(
|
||||
"Schema-validation: wrong column type encountered in column [%s] in " +
|
||||
|
|
|
@ -27,7 +27,7 @@ import static org.hibernate.type.SqlTypes.isStringType;
|
|||
class ColumnDefinitions {
|
||||
|
||||
static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
|
||||
boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode(metadata), columnInformation.getTypeCode() )
|
||||
final boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode( metadata ), columnInformation.getTypeCode() )
|
||||
|| normalize( stripArgs( column.getSqlType( metadata ) ) ).equals( normalize( columnInformation.getTypeName() ) );
|
||||
if ( typesMatch ) {
|
||||
return true;
|
||||
|
@ -42,7 +42,7 @@ class ColumnDefinitions {
|
|||
columnInformation.getDecimalDigits(),
|
||||
metadata.getDatabase().getTypeConfiguration().getJdbcTypeRegistry()
|
||||
);
|
||||
return dialect.equivalentTypes( column.getSqlTypeCode(metadata), jdbcType.getDefaultSqlTypeCode() );
|
||||
return dialect.equivalentTypes( column.getSqlTypeCode( metadata ), jdbcType.getDefaultSqlTypeCode() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue