HHH-17276 Expose size based lob-ness in DdlType and retain info in runtime model

This commit is contained in:
Christian Beikov 2023-09-29 10:30:32 +02:00
parent c67403e01f
commit 67643c4c23
33 changed files with 487 additions and 88 deletions

View File

@ -174,7 +174,7 @@ ext {
// //
// To avoid hibernate-spatial tests failure, JVM must be enabled as stated in documentation: // To avoid hibernate-spatial tests failure, JVM must be enabled as stated in documentation:
// https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/autonomous-oracle-java.html // https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/autonomous-oracle-java.html
'jdbc.url' : 'jdbc:oracle:thin:@(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=' + dbHost + '.oraclecloud.com))(connect_data=(service_name=' + dbService + '_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))', 'jdbc.url' : 'jdbc:oracle:thin:@(description=(retry_count=5)(retry_delay=1)(address=(protocol=tcps)(port=1521)(host=' + dbHost + '.oraclecloud.com))(connect_data=(service_name=' + dbService + '_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=no)))?oracle.jdbc.enableQueryResultCache=false&oracle.jdbc.thinForceDNSLoadBalancing=true&tcp.nodelay=yes',
'connection.init_sql' : '' 'connection.init_sql' : ''
], ],
oracle_cloud_db19c : [ oracle_cloud_db19c : [

View File

@ -106,7 +106,12 @@ public class CUBRIDDialect extends Dialect {
//length parameter is measured in bits, not bytes) //length parameter is measured in bits, not bytes)
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( BINARY, "bit($l)", this ) ); ddlTypeRegistry.addDescriptor( new DdlTypeImpl( BINARY, "bit($l)", this ) );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARBINARY, columnType( BLOB ), this ) CapacityDependentDdlType.builder(
VARBINARY,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( BLOB ),
this
)
.withTypeCapacity( getMaxVarbinaryLength(), "bit varying($l)" ) .withTypeCapacity( getMaxVarbinaryLength(), "bit varying($l)" )
.build() .build()
); );

View File

@ -185,23 +185,55 @@ public class DerbyLegacyDialect extends Dialect {
int varcharDdlTypeCapacity = 32_672; int varcharDdlTypeCapacity = 32_672;
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARBINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) CapacityDependentDdlType.builder(
VARBINARY,
isLob( LONG32VARBINARY )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARBINARY ),
columnType( VARBINARY ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), columnType( VARCHAR ), this ) CapacityDependentDdlType.builder(
VARCHAR,
isLob( LONG32VARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( VARCHAR ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NVARCHAR, columnType( LONG32VARCHAR ), columnType( NVARCHAR ), this ) CapacityDependentDdlType.builder(
NVARCHAR,
isLob( LONG32NVARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( NVARCHAR ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) CapacityDependentDdlType.builder(
BINARY,
isLob( LONG32VARBINARY )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARBINARY ),
columnType( VARBINARY ),
this
)
.withTypeCapacity( 254, "char($l) for bit data" ) .withTypeCapacity( 254, "char($l) for bit data" )
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build() .build()
@ -209,13 +241,29 @@ public class DerbyLegacyDialect extends Dialect {
// This is the maximum size for the CHAR datatype on Derby // This is the maximum size for the CHAR datatype on Derby
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( CHAR, columnType( LONG32VARCHAR ), columnType( CHAR ), this ) CapacityDependentDdlType.builder(
CHAR,
isLob( LONG32VARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( CHAR ),
this
)
.withTypeCapacity( 254, columnType( CHAR ) ) .withTypeCapacity( 254, columnType( CHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NCHAR, columnType( LONG32NVARCHAR ), columnType( NCHAR ), this ) CapacityDependentDdlType.builder(
NCHAR,
isLob( LONG32NVARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32NVARCHAR ),
columnType( NCHAR ),
this
)
.withTypeCapacity( 254, columnType( NCHAR ) ) .withTypeCapacity( 254, columnType( NCHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) )
.build() .build()

View File

@ -42,6 +42,7 @@ import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.CHAR; import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.CLOB; import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR; import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARBINARY;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR; import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR; import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB; import static org.hibernate.type.SqlTypes.NCLOB;
@ -113,7 +114,15 @@ public class MimerSQLDialect extends Dialect {
//Mimer CHARs are ASCII!! //Mimer CHARs are ASCII!!
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), "nvarchar(" + getMaxNVarcharLength() + ")", this ) CapacityDependentDdlType.builder(
VARCHAR,
isLob( LONG32VARCHAR ) ?
CapacityDependentDdlType.LobKind.BIGGEST_LOB :
CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
"nvarchar(" + getMaxNVarcharLength() + ")",
this
)
.withTypeCapacity( getMaxNVarcharLength(), columnType( VARCHAR ) ) .withTypeCapacity( getMaxNVarcharLength(), columnType( VARCHAR ) )
.build() .build()
); );

View File

@ -300,8 +300,14 @@ public class MySQLLegacyDialect extends Dialect {
final int maxMediumLobLen = 16_777_215; final int maxMediumLobLen = 16_777_215;
final CapacityDependentDdlType.Builder varcharBuilder = final CapacityDependentDdlType.Builder varcharBuilder =
CapacityDependentDdlType.builder( VARCHAR, CapacityDependentDdlType.builder(
columnType( CLOB ), columnType( CHAR ), castType( CHAR ), this ) VARCHAR,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( CLOB ),
columnType( CHAR ),
castType( CHAR ),
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" ) .withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" ); .withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) { if ( getMaxVarcharLength() < maxLobLen ) {
@ -310,8 +316,14 @@ public class MySQLLegacyDialect extends Dialect {
ddlTypeRegistry.addDescriptor( varcharBuilder.build() ); ddlTypeRegistry.addDescriptor( varcharBuilder.build() );
final CapacityDependentDdlType.Builder nvarcharBuilder = final CapacityDependentDdlType.Builder nvarcharBuilder =
CapacityDependentDdlType.builder( NVARCHAR, CapacityDependentDdlType.builder(
columnType( NCLOB ), columnType( NCHAR ), castType( NCHAR ), this ) NVARCHAR,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( NCLOB ),
columnType( NCHAR ),
castType( NCHAR ),
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" ) .withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" ); .withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) { if ( getMaxVarcharLength() < maxLobLen ) {
@ -320,8 +332,14 @@ public class MySQLLegacyDialect extends Dialect {
ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() ); ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() );
final CapacityDependentDdlType.Builder varbinaryBuilder = final CapacityDependentDdlType.Builder varbinaryBuilder =
CapacityDependentDdlType.builder( VARBINARY, CapacityDependentDdlType.builder(
columnType( BLOB ), columnType( BINARY ), castType( BINARY ), this ) VARBINARY,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( BLOB ),
columnType( BINARY ),
castType( BINARY ),
this
)
.withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" ) .withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumblob" ); .withTypeCapacity( maxMediumLobLen, "mediumblob" );
if ( getMaxVarbinaryLength() < maxLobLen ) { if ( getMaxVarbinaryLength() < maxLobLen ) {

View File

@ -299,7 +299,7 @@ public abstract class AbstractHANADialect extends Dialect {
// varbinary max length 5000 // varbinary max length 5000
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, "blob", this ) CapacityDependentDdlType.builder( BINARY, CapacityDependentDdlType.LobKind.BIGGEST_LOB, "blob", this )
.withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" ) .withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" )
.build() .build()
); );

View File

@ -182,23 +182,55 @@ public class DerbyDialect extends Dialect {
int varcharDdlTypeCapacity = 32_672; int varcharDdlTypeCapacity = 32_672;
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARBINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) CapacityDependentDdlType.builder(
VARBINARY,
isLob( LONG32VARBINARY )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARBINARY ),
columnType( VARBINARY ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), columnType( VARCHAR ), this ) CapacityDependentDdlType.builder(
VARCHAR,
isLob( LONG32VARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( VARCHAR ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NVARCHAR, columnType( LONG32VARCHAR ), columnType( NVARCHAR ), this ) CapacityDependentDdlType.builder(
NVARCHAR,
isLob( LONG32NVARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( NVARCHAR ),
this
)
.withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) CapacityDependentDdlType.builder(
BINARY,
isLob( LONG32VARBINARY )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARBINARY ),
columnType( VARBINARY ),
this
)
.withTypeCapacity( 254, "char($l) for bit data" ) .withTypeCapacity( 254, "char($l) for bit data" )
.withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build() .build()
@ -206,13 +238,29 @@ public class DerbyDialect extends Dialect {
// This is the maximum size for the CHAR datatype on Derby // This is the maximum size for the CHAR datatype on Derby
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( CHAR, columnType( LONG32VARCHAR ), columnType( CHAR ), this ) CapacityDependentDdlType.builder(
CHAR,
isLob( LONG32VARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32VARCHAR ),
columnType( CHAR ),
this
)
.withTypeCapacity( 254, columnType( CHAR ) ) .withTypeCapacity( 254, columnType( CHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.build() .build()
); );
ddlTypeRegistry.addDescriptor( ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NCHAR, columnType( LONG32NVARCHAR ), columnType( NCHAR ), this ) CapacityDependentDdlType.builder(
NCHAR,
isLob( LONG32NVARCHAR )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( LONG32NVARCHAR ),
columnType( NCHAR ),
this
)
.withTypeCapacity( 254, columnType( NCHAR ) ) .withTypeCapacity( 254, columnType( NCHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) )
.build() .build()

View File

@ -446,10 +446,33 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
if ( supportsStandardArrays() ) { if ( supportsStandardArrays() ) {
ddlTypeRegistry.addDescriptor( new ArrayDdlTypeImpl( this ) ); ddlTypeRegistry.addDescriptor( new ArrayDdlTypeImpl( this ) );
} }
if ( rowId( null ) != null ) {
ddlTypeRegistry.addDescriptor( simpleSqlType( ROWID ) );
}
}
protected boolean isLob(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case LONG32VARBINARY:
case LONG32VARCHAR:
case LONG32NVARCHAR:
case BLOB:
case CLOB:
case NCLOB:
return true;
default:
return false;
}
} }
private DdlTypeImpl simpleSqlType(int sqlTypeCode) { private DdlTypeImpl simpleSqlType(int sqlTypeCode) {
return new DdlTypeImpl( sqlTypeCode, columnType( sqlTypeCode ), castType( sqlTypeCode ), this ); return new DdlTypeImpl(
sqlTypeCode,
isLob( sqlTypeCode ),
columnType( sqlTypeCode ),
castType( sqlTypeCode ),
this
);
} }
/** /**
@ -463,6 +486,11 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
private CapacityDependentDdlType.Builder sqlTypeBuilder(int sqlTypeCode, int biggestSqlTypeCode, int castTypeCode) { private CapacityDependentDdlType.Builder sqlTypeBuilder(int sqlTypeCode, int biggestSqlTypeCode, int castTypeCode) {
return CapacityDependentDdlType.builder( return CapacityDependentDdlType.builder(
sqlTypeCode, sqlTypeCode,
isLob( sqlTypeCode )
? CapacityDependentDdlType.LobKind.ALL_LOB
: isLob( biggestSqlTypeCode )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( biggestSqlTypeCode ), columnType( biggestSqlTypeCode ),
castType( castTypeCode ), castType( castTypeCode ),
this this
@ -510,6 +538,9 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
*/ */
protected String columnType(int sqlTypeCode) { protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) { switch ( sqlTypeCode ) {
case ROWID:
return "rowid";
case BOOLEAN: case BOOLEAN:
return "boolean"; return "boolean";

View File

@ -334,8 +334,14 @@ public class MySQLDialect extends Dialect {
final int maxMediumLobLen = 16_777_215; final int maxMediumLobLen = 16_777_215;
final CapacityDependentDdlType.Builder varcharBuilder = final CapacityDependentDdlType.Builder varcharBuilder =
CapacityDependentDdlType.builder( VARCHAR, CapacityDependentDdlType.builder(
columnType( CLOB ), columnType( CHAR ), castType( CHAR ), this ) VARCHAR,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( CLOB ),
columnType( CHAR ),
castType( CHAR ),
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" ) .withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" ); .withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) { if ( getMaxVarcharLength() < maxLobLen ) {
@ -346,8 +352,14 @@ public class MySQLDialect extends Dialect {
// do not use nchar/nvarchar/ntext because these // do not use nchar/nvarchar/ntext because these
// types use a deprecated character set on MySQL 8 // types use a deprecated character set on MySQL 8
final CapacityDependentDdlType.Builder nvarcharBuilder = final CapacityDependentDdlType.Builder nvarcharBuilder =
CapacityDependentDdlType.builder( NVARCHAR, CapacityDependentDdlType.builder(
columnType( NCLOB ), columnType( NCHAR ), castType( NCHAR ), this ) NVARCHAR,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( NCLOB ),
columnType( NCHAR ),
castType( NCHAR ),
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l) character set utf8" ) .withTypeCapacity( getMaxVarcharLength(), "varchar($l) character set utf8" )
.withTypeCapacity( maxMediumLobLen, "mediumtext character set utf8" ); .withTypeCapacity( maxMediumLobLen, "mediumtext character set utf8" );
if ( getMaxVarcharLength() < maxLobLen ) { if ( getMaxVarcharLength() < maxLobLen ) {
@ -356,8 +368,14 @@ public class MySQLDialect extends Dialect {
ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() ); ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() );
final CapacityDependentDdlType.Builder varbinaryBuilder = final CapacityDependentDdlType.Builder varbinaryBuilder =
CapacityDependentDdlType.builder( VARBINARY, CapacityDependentDdlType.builder(
columnType( BLOB ), columnType( BINARY ), castType( BINARY ), this ) VARBINARY,
CapacityDependentDdlType.LobKind.BIGGEST_LOB,
columnType( BLOB ),
columnType( BINARY ),
castType( BINARY ),
this
)
.withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" ) .withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumblob" ); .withTypeCapacity( maxMediumLobLen, "mediumblob" );
if ( getMaxVarbinaryLength() < maxLobLen ) { if ( getMaxVarbinaryLength() < maxLobLen ) {

View File

@ -28,6 +28,8 @@ import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.sql.DdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
@ -56,6 +58,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private boolean unique; private boolean unique;
private String sqlTypeName; private String sqlTypeName;
private Integer sqlTypeCode; private Integer sqlTypeCode;
private boolean sqlTypeLob;
private boolean quoted; private boolean quoted;
private boolean explicit; private boolean explicit;
int uniqueInteger; int uniqueInteger;
@ -284,13 +287,29 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private String getSqlTypeName(DdlTypeRegistry ddlTypeRegistry, Dialect dialect, Mapping mapping) { private String getSqlTypeName(DdlTypeRegistry ddlTypeRegistry, Dialect dialect, Mapping mapping) {
if ( sqlTypeName == null ) { if ( sqlTypeName == null ) {
try { final int typeCode = getSqlTypeCode( mapping );
sqlTypeName = ddlTypeRegistry.getTypeName( final DdlType descriptor = ddlTypeRegistry.getDescriptor( getSqlTypeCode( mapping ) );
getSqlTypeCode( mapping ), if ( descriptor == null ) {
getColumnSize( dialect, mapping ), throw new MappingException(
getUnderlyingType( mapping, getValue().getType(), typeIndex ) String.format(
Locale.ROOT,
"Unable to determine SQL type name for column '%s' of table '%s' because there is no type mapping for org.hibernate.type.SqlTypes code: %s (%s)",
getName(),
getValue().getTable().getName(),
typeCode,
JdbcTypeNameMapper.getTypeName( typeCode )
)
); );
} }
try {
final Size size = getColumnSize( dialect, mapping );
sqlTypeName = descriptor.getTypeName(
size,
getUnderlyingType( mapping, getValue().getType(), typeIndex ),
ddlTypeRegistry
);
sqlTypeLob = descriptor.isLob( size );
}
catch ( Exception cause ) { catch ( Exception cause ) {
throw new MappingException( throw new MappingException(
String.format( String.format(
@ -489,6 +508,10 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
sqlTypeName = typeName; sqlTypeName = typeName;
} }
public boolean isSqlTypeLob() {
return sqlTypeLob;
}
public void setUnique(boolean unique) { public void setUnique(boolean unique) {
this.unique = unique; this.unique = unique;
} }

View File

@ -16,5 +16,8 @@ public interface SqlTypedMapping {
Long getLength(); Long getLength();
Integer getPrecision(); Integer getPrecision();
Integer getScale(); Integer getScale();
default boolean isLob() {
return getJdbcMapping().getJdbcType().isLob();
}
JdbcMapping getJdbcMapping(); JdbcMapping getJdbcMapping();
} }

View File

@ -283,14 +283,16 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
final Long length; final Long length;
final Integer precision; final Integer precision;
final Integer scale; final Integer scale;
final boolean isLob;
final boolean nullable; final boolean nullable;
if ( selectable instanceof Column ) { if ( selectable instanceof Column ) {
final Column column = (Column) selectable; final Column column = (Column) selectable;
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
nullable = column.isNullable(); nullable = column.isNullable();
isLob = column.isSqlTypeLob();
selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) ); selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) );
} }
else { else {
@ -299,6 +301,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
precision = null; precision = null;
scale = null; scale = null;
nullable = true; nullable = true;
isLob = false;
selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() ); selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() );
} }
@ -320,6 +323,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
length, length,
precision, precision,
scale, scale,
isLob,
nullable, nullable,
value.isColumnInsertable( 0 ), value.isColumnInsertable( 0 ),
value.isColumnUpdateable( 0 ), value.isColumnUpdateable( 0 ),

View File

@ -60,6 +60,7 @@ public class BasicAttributeMapping
private final Integer scale; private final Integer scale;
private final JdbcMapping jdbcMapping; private final JdbcMapping jdbcMapping;
private final boolean isLob;
private final boolean nullable; private final boolean nullable;
private final boolean insertable; private final boolean insertable;
private final boolean updateable; private final boolean updateable;
@ -85,6 +86,7 @@ public class BasicAttributeMapping
Long length, Long length,
Integer precision, Integer precision,
Integer scale, Integer scale,
boolean isLob,
boolean nullable, boolean nullable,
boolean insertable, boolean insertable,
boolean updateable, boolean updateable,
@ -116,6 +118,7 @@ public class BasicAttributeMapping
this.length = length; this.length = length;
this.precision = precision; this.precision = precision;
this.scale = scale; this.scale = scale;
this.isLob = isLob;
this.nullable = nullable; this.nullable = nullable;
this.insertable = insertable; this.insertable = insertable;
this.updateable = updateable; this.updateable = updateable;
@ -183,6 +186,7 @@ public class BasicAttributeMapping
selectableMapping.getLength(), selectableMapping.getLength(),
selectableMapping.getPrecision(), selectableMapping.getPrecision(),
selectableMapping.getScale(), selectableMapping.getScale(),
selectableMapping.isLob(),
selectableMapping.isNullable(), selectableMapping.isNullable(),
insertable, insertable,
updateable, updateable,
@ -223,6 +227,11 @@ public class BasicAttributeMapping
return selectablePath; return selectablePath;
} }
@Override
public boolean isLob() {
return isLob;
}
@Override @Override
public boolean isFormula() { public boolean isFormula() {
return isFormula; return isFormula;

View File

@ -86,7 +86,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
declaringModelPart, declaringModelPart,
tableName, tableName,
metaColumn.getText( dialect ), metaColumn.getText( dialect ),
metaColumn.getSqlType(), metaColumn.getSqlType( creationProcess.getCreationContext().getMetadata() ),
metaColumn.getLength(), metaColumn.getLength(),
metaColumn.getPrecision(), metaColumn.getPrecision(),
metaColumn.getScale(), metaColumn.getScale(),
@ -105,7 +105,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
declaringModelPart, declaringModelPart,
tableName, tableName,
keyColumn.getText( dialect ), keyColumn.getText( dialect ),
keyColumn.getSqlType(), keyColumn.getSqlType( creationProcess.getCreationContext().getMetadata() ),
keyColumn.getLength(), keyColumn.getLength(),
keyColumn.getPrecision(), keyColumn.getPrecision(),
keyColumn.getScale(), keyColumn.getScale(),

View File

@ -193,7 +193,8 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
updatable, updatable,
false, false,
dialect, dialect,
null null,
creationContext
); );
final AggregateSupport aggregateSupport = dialect.getAggregateSupport(); final AggregateSupport aggregateSupport = dialect.getAggregateSupport();
final int sqlTypeCode = aggregateColumn.getSqlTypeCode(); final int sqlTypeCode = aggregateColumn.getSqlTypeCode();
@ -227,7 +228,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
typeConfiguration.getJdbcTypeRegistry().resolveAggregateDescriptor( typeConfiguration.getJdbcTypeRegistry().resolveAggregateDescriptor(
aggregateColumn.getSqlTypeCode(), aggregateColumn.getSqlTypeCode(),
aggregateColumn.getSqlTypeCode() == SqlTypes.STRUCT aggregateColumn.getSqlTypeCode() == SqlTypes.STRUCT
? aggregateColumn.getSqlType() ? aggregateColumn.getSqlType( creationContext.getMetadata() )
: null, : null,
this, this,
creationContext creationContext
@ -378,13 +379,15 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
final Long length; final Long length;
final Integer precision; final Integer precision;
final Integer scale; final Integer scale;
final boolean isLob;
final boolean nullable; final boolean nullable;
if ( selectable instanceof Column ) { if ( selectable instanceof Column ) {
final Column column = (Column) selectable; final Column column = (Column) selectable;
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
isLob = column.isSqlTypeLob();
nullable = bootPropertyDescriptor.isOptional() && column.isNullable() ; nullable = bootPropertyDescriptor.isOptional() && column.isNullable() ;
selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) ); selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) );
} }
@ -393,6 +396,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
length = null; length = null;
precision = null; precision = null;
scale = null; scale = null;
isLob = false;
nullable = bootPropertyDescriptor.isOptional(); nullable = bootPropertyDescriptor.isOptional();
selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() ); selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() );
} }
@ -414,6 +418,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
length, length,
precision, precision,
scale, scale,
isLob,
nullable, nullable,
insertability[columnPosition], insertability[columnPosition],
updateability[columnPosition], updateability[columnPosition],

View File

@ -502,7 +502,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
false, false,
false, false,
creationProcess.getCreationContext().getDialect(), creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
final BasicAttributeMapping keyModelPart = BasicAttributeMapping.withSelectableMapping( final BasicAttributeMapping keyModelPart = BasicAttributeMapping.withSelectableMapping(
@ -538,7 +539,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
elementBootDescriptor.getColumnInsertability(), elementBootDescriptor.getColumnInsertability(),
elementBootDescriptor.getColumnUpdateability(), elementBootDescriptor.getColumnUpdateability(),
creationProcess.getCreationContext().getDialect(), creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
return new EmbeddedForeignKeyDescriptor( return new EmbeddedForeignKeyDescriptor(
@ -676,7 +678,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
fkBootDescriptorSource.getColumnInsertability(), fkBootDescriptorSource.getColumnInsertability(),
fkBootDescriptorSource.getColumnUpdateability(), fkBootDescriptorSource.getColumnUpdateability(),
creationProcess.getCreationContext().getDialect(), creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
return foreignKeyDescriptor.withKeySelectionMapping( return foreignKeyDescriptor.withKeySelectionMapping(
declaringType, declaringType,
@ -718,7 +721,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
columnUpdateable, columnUpdateable,
fkValue.isPartitionKey(), fkValue.isPartitionKey(),
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
// here we build a ModelPart that represents the many-to-many table key referring to the element table // here we build a ModelPart that represents the many-to-many table key referring to the element table

View File

@ -194,6 +194,7 @@ public class MappingModelCreationHelper {
Long length, Long length,
Integer precision, Integer precision,
Integer scale, Integer scale,
boolean isLob,
boolean nullable, boolean nullable,
boolean insertable, boolean insertable,
boolean updateable, boolean updateable,
@ -243,6 +244,7 @@ public class MappingModelCreationHelper {
length, length,
precision, precision,
scale, scale,
isLob,
nullable, nullable,
insertable, insertable,
updateable, updateable,
@ -512,7 +514,8 @@ public class MappingModelCreationHelper {
index.isColumnUpdateable( 0 ), index.isColumnUpdateable( 0 ),
false, false,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
indexDescriptor = new BasicValuedCollectionPart( indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor, collectionDescriptor,
@ -565,7 +568,8 @@ public class MappingModelCreationHelper {
index.isColumnUpdateable( 0 ), index.isColumnUpdateable( 0 ),
false, false,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
indexDescriptor = new BasicValuedCollectionPart( indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor, collectionDescriptor,
@ -776,7 +780,8 @@ public class MappingModelCreationHelper {
bootValueMappingKey.isColumnUpdateable( 0 ), bootValueMappingKey.isColumnUpdateable( 0 ),
false, false,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
final SimpleForeignKeyDescriptor keyDescriptor = new SimpleForeignKeyDescriptor( final SimpleForeignKeyDescriptor keyDescriptor = new SimpleForeignKeyDescriptor(
@ -952,7 +957,8 @@ public class MappingModelCreationHelper {
value.isColumnUpdateable( i ), value.isColumnUpdateable( i ),
((SimpleValue) value).isPartitionKey(), ((SimpleValue) value).isPartitionKey(),
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
i++; i++;
} }
@ -967,7 +973,8 @@ public class MappingModelCreationHelper {
value.isColumnUpdateable( 0 ), value.isColumnUpdateable( 0 ),
((SimpleValue) value).isPartitionKey(), ((SimpleValue) value).isPartitionKey(),
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
} }
@ -1114,7 +1121,8 @@ public class MappingModelCreationHelper {
insertable, insertable,
updateable, updateable,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
} }
else { else {
@ -1138,7 +1146,8 @@ public class MappingModelCreationHelper {
insertable, insertable,
updateable, updateable,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
} }
if ( inverse ) { if ( inverse ) {
@ -1318,7 +1327,8 @@ public class MappingModelCreationHelper {
updatable, updatable,
false, false,
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
return new BasicValuedCollectionPart( return new BasicValuedCollectionPart(
collectionDescriptor, collectionDescriptor,
@ -1415,7 +1425,8 @@ public class MappingModelCreationHelper {
basicElement.isPartitionKey(), basicElement.isPartitionKey(),
true, // element collection does not support null elements true, // element collection does not support null elements
dialect, dialect,
creationProcess.getSqmFunctionRegistry() creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
); );
return new BasicValuedCollectionPart( return new BasicValuedCollectionPart(
collectionDescriptor, collectionDescriptor,

View File

@ -14,6 +14,7 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectablePath; import org.hibernate.metamodel.mapping.SelectablePath;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
@ -27,6 +28,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
private final SelectablePath selectablePath; private final SelectablePath selectablePath;
private final String customReadExpression; private final String customReadExpression;
private final String customWriteExpression; private final String customWriteExpression;
private final boolean isLob;
private final boolean nullable; private final boolean nullable;
private final boolean insertable; private final boolean insertable;
private final boolean updateable; private final boolean updateable;
@ -43,6 +45,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
Long length, Long length,
Integer precision, Integer precision,
Integer scale, Integer scale,
boolean isLob,
boolean nullable, boolean nullable,
boolean insertable, boolean insertable,
boolean updateable, boolean updateable,
@ -57,6 +60,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
this.selectablePath = selectablePath == null ? new SelectablePath( selectionExpression ) : selectablePath; this.selectablePath = selectablePath == null ? new SelectablePath( selectionExpression ) : selectablePath;
this.customReadExpression = customReadExpression == null ? null : customReadExpression.intern(); this.customReadExpression = customReadExpression == null ? null : customReadExpression.intern();
this.customWriteExpression = customWriteExpression == null || isFormula ? null : customWriteExpression.intern(); this.customWriteExpression = customWriteExpression == null || isFormula ? null : customWriteExpression.intern();
this.isLob = isLob;
this.nullable = nullable; this.nullable = nullable;
this.insertable = insertable; this.insertable = insertable;
this.updateable = updateable; this.updateable = updateable;
@ -73,7 +77,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
boolean updateable, boolean updateable,
boolean partitioned, boolean partitioned,
final Dialect dialect, final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) { final SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
return from( return from(
containingTableExpression, containingTableExpression,
selectable, selectable,
@ -84,7 +89,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
updateable, updateable,
partitioned, partitioned,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }
@ -98,7 +104,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
boolean partitioned, boolean partitioned,
boolean forceNotNullable, boolean forceNotNullable,
final Dialect dialect, final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) { final SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
return from( return from(
containingTableExpression, containingTableExpression,
selectable, selectable,
@ -110,7 +117,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
partitioned, partitioned,
forceNotNullable, forceNotNullable,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }
@ -124,7 +132,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
boolean updateable, boolean updateable,
boolean partitioned, boolean partitioned,
final Dialect dialect, final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) { final SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
return from( return from(
containingTableExpression, containingTableExpression,
selectable, selectable,
@ -136,7 +145,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
partitioned, partitioned,
false, false,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }
@ -151,13 +161,15 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
boolean partitioned, boolean partitioned,
boolean forceNotNullable, boolean forceNotNullable,
final Dialect dialect, final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) { final SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
final String columnExpression; final String columnExpression;
final String columnDefinition; final String columnDefinition;
final Long length; final Long length;
final Integer precision; final Integer precision;
final Integer scale; final Integer scale;
final String selectableName; final String selectableName;
final boolean isLob;
final boolean isNullable; final boolean isNullable;
if ( selectable.isFormula() ) { if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, typeConfiguration, sqmFunctionRegistry ); columnExpression = selectable.getTemplate( dialect, typeConfiguration, sqmFunctionRegistry );
@ -166,17 +178,19 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
precision = null; precision = null;
scale = null; scale = null;
isNullable = true; isNullable = true;
isLob = false;
selectableName = selectable.getText(); selectableName = selectable.getText();
} }
else { else {
Column column = (Column) selectable; Column column = (Column) selectable;
columnExpression = selectable.getText( dialect ); columnExpression = selectable.getText( dialect );
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationContext.getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
isNullable = forceNotNullable ? false : column.isNullable(); isNullable = forceNotNullable ? false : column.isNullable();
isLob = column.isSqlTypeLob();
selectableName = column.getQuotedName( dialect ); selectableName = column.getQuotedName( dialect );
} }
return new SelectableMappingImpl( return new SelectableMappingImpl(
@ -191,6 +205,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
length, length,
precision, precision,
scale, scale,
isLob,
isNullable, isNullable,
insertable, insertable,
updateable, updateable,
@ -245,6 +260,11 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
return customWriteExpression; return customWriteExpression;
} }
@Override
public boolean isLob() {
return isLob;
}
@Override @Override
public boolean isFormula() { public boolean isFormula() {
return isFormula; return isFormula;

View File

@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectableMappings; import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
@ -64,7 +65,8 @@ public class SelectableMappingsImpl implements SelectableMappings {
boolean[] insertable, boolean[] insertable,
boolean[] updateable, boolean[] updateable,
Dialect dialect, Dialect dialect,
SqmFunctionRegistry sqmFunctionRegistry) { SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
if ( insertable.length == 0 ) { if ( insertable.length == 0 ) {
return from( return from(
containingTableExpression, containingTableExpression,
@ -73,7 +75,8 @@ public class SelectableMappingsImpl implements SelectableMappings {
mapping, mapping,
typeConfiguration, typeConfiguration,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }
final List<JdbcMapping> jdbcMappings = new ArrayList<>(); final List<JdbcMapping> jdbcMappings = new ArrayList<>();
@ -92,7 +95,8 @@ public class SelectableMappingsImpl implements SelectableMappings {
updateable[i], updateable[i],
false, false,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }
@ -106,7 +110,8 @@ public class SelectableMappingsImpl implements SelectableMappings {
Mapping mapping, Mapping mapping,
TypeConfiguration typeConfiguration, TypeConfiguration typeConfiguration,
Dialect dialect, Dialect dialect,
SqmFunctionRegistry sqmFunctionRegistry) { SqmFunctionRegistry sqmFunctionRegistry,
RuntimeModelCreationContext creationContext) {
final List<JdbcMapping> jdbcMappings = new ArrayList<>(); final List<JdbcMapping> jdbcMappings = new ArrayList<>();
resolveJdbcMappings( jdbcMappings, mapping, value.getType() ); resolveJdbcMappings( jdbcMappings, mapping, value.getType() );
@ -123,7 +128,8 @@ public class SelectableMappingsImpl implements SelectableMappings {
false, false,
false, false,
dialect, dialect,
sqmFunctionRegistry sqmFunctionRegistry,
creationContext
); );
} }

View File

@ -555,7 +555,8 @@ public class OneToManyPersister extends AbstractCollectionPersister {
updateBuilder.addValueColumn( updateBuilder.addValueColumn(
selectable.getSelectionExpression(), selectable.getSelectionExpression(),
NULL, NULL,
selectable.getJdbcMapping() selectable.getJdbcMapping(),
selectable.isLob()
); );
} }
@ -578,7 +579,8 @@ public class OneToManyPersister extends AbstractCollectionPersister {
updateBuilder.addValueColumn( updateBuilder.addValueColumn(
selectable.getSelectionExpression(), selectable.getSelectionExpression(),
NULL, NULL,
selectable.getJdbcMapping() selectable.getJdbcMapping(),
selectable.isLob()
); );
} }
} }

View File

@ -5202,7 +5202,7 @@ public abstract class AbstractEntityPersister
scale = null; scale = null;
} }
else { else {
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( modelCreationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
@ -5379,7 +5379,7 @@ public abstract class AbstractEntityPersister
} }
else { else {
Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 );
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
@ -5438,7 +5438,7 @@ public abstract class AbstractEntityPersister
bootModelRootEntityDescriptor.getVersion().getName(), bootModelRootEntityDescriptor.getVersion().getName(),
entityPersister.getTableName(), entityPersister.getTableName(),
column.getText( dialect ), column.getText( dialect ),
column.getSqlType(), column.getSqlType( creationProcess.getCreationContext().getMetadata() ),
column.getLength(), column.getLength(),
column.getPrecision(), column.getPrecision(),
column.getScale(), column.getScale(),
@ -5483,10 +5483,11 @@ public abstract class AbstractEntityPersister
false, false,
null, null,
"?", "?",
column.getSqlType(), column.getSqlType( creationProcess.getCreationContext().getMetadata() ),
column.getLength(), column.getLength(),
column.getPrecision(), column.getPrecision(),
column.getScale(), column.getScale(),
column.isSqlTypeLob(),
column.isNullable(), column.isNullable(),
value.isColumnInsertable( 0 ), value.isColumnInsertable( 0 ),
value.isColumnUpdateable( 0 ), value.isColumnUpdateable( 0 ),
@ -5505,6 +5506,7 @@ public abstract class AbstractEntityPersister
final Long length; final Long length;
final Integer precision; final Integer precision;
final Integer scale; final Integer scale;
final boolean isLob;
final boolean nullable; final boolean nullable;
if ( value instanceof DependantValue ) { if ( value instanceof DependantValue ) {
@ -5513,10 +5515,11 @@ public abstract class AbstractEntityPersister
customReadExpr = null; customReadExpr = null;
customWriteExpr = "?"; customWriteExpr = "?";
Column column = value.getColumns().get( 0 ); Column column = value.getColumns().get( 0 );
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
isLob = column.isSqlTypeLob();
nullable = column.isNullable(); nullable = column.isNullable();
} }
else { else {
@ -5539,11 +5542,12 @@ public abstract class AbstractEntityPersister
); );
customWriteExpr = selectable.getWriteExpr( (JdbcMapping) attrType, creationContext.getDialect() ); customWriteExpr = selectable.getWriteExpr( (JdbcMapping) attrType, creationContext.getDialect() );
Column column = value.getColumns().get( 0 ); Column column = value.getColumns().get( 0 );
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationContext.getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();
nullable = column.isNullable(); nullable = column.isNullable();
isLob = column.isSqlTypeLob();
} }
else { else {
final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ]; final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ];
@ -5556,6 +5560,7 @@ public abstract class AbstractEntityPersister
precision = null; precision = null;
scale = null; scale = null;
nullable = true; nullable = true;
isLob = false;
} }
} }
@ -5577,6 +5582,7 @@ public abstract class AbstractEntityPersister
length, length,
precision, precision,
scale, scale,
isLob,
nullable, nullable,
value.isColumnInsertable( 0 ), value.isColumnInsertable( 0 ),
value.isColumnUpdateable( 0 ), value.isColumnUpdateable( 0 ),

View File

@ -1187,7 +1187,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
else { else {
final Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); final Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 );
columnDefinition = column.getSqlType(); columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength(); length = column.getLength();
precision = column.getPrecision(); precision = column.getPrecision();
scale = column.getScale(); scale = column.getScale();

View File

@ -130,7 +130,8 @@ public abstract class AbstractMutationCoordinator {
tableUpdateBuilder.addValueColumn( tableUpdateBuilder.addValueColumn(
mapping.getSelectionExpression(), mapping.getSelectionExpression(),
writePropertyValue ? "?" : columnValues[j], writePropertyValue ? "?" : columnValues[j],
mapping.getJdbcMapping() mapping.getJdbcMapping(),
mapping.isLob()
); );
} ); } );
} }

View File

@ -70,10 +70,10 @@ public abstract class AbstractTableInsertBuilder
} }
@Override @Override
public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) { public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob) {
final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping ); final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping );
if ( jdbcMapping.getJdbcType().isLob() && getJdbcServices().getDialect().forceLobAsLastValue() ) { if ( isLob && getJdbcServices().getDialect().forceLobAsLastValue() ) {
if ( lobValueBindingList == null ) { if ( lobValueBindingList == null ) {
lobValueBindingList = new ArrayList<>(); lobValueBindingList = new ArrayList<>();
} }

View File

@ -90,10 +90,11 @@ public abstract class AbstractTableUpdateBuilder<O extends MutationOperation>
public void addValueColumn( public void addValueColumn(
String columnName, String columnName,
String columnWriteFragment, String columnWriteFragment,
JdbcMapping jdbcMapping) { JdbcMapping jdbcMapping,
boolean isLob) {
final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping ); final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping );
if ( jdbcMapping.getJdbcType().isLob() && getJdbcServices().getDialect().forceLobAsLastValue() ) { if ( isLob && getJdbcServices().getDialect().forceLobAsLastValue() ) {
if ( lobValueBindings == null ) { if ( lobValueBindings == null ) {
lobValueBindings = new ArrayList<>(); lobValueBindings = new ArrayList<>();
} }

View File

@ -19,7 +19,13 @@ public interface ColumnValuesTableMutationBuilder {
/** /**
* Add a column as part of the values list * Add a column as part of the values list
*/ */
void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping); void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob);
/**
* Add a column as part of the values list
*/
default void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) {
addValueColumn( columnName, columnWriteFragment, jdbcMapping, jdbcMapping.getJdbcType().isLob() );
}
/** /**
* Add a column as part of the values list * Add a column as part of the values list
@ -28,7 +34,8 @@ public interface ColumnValuesTableMutationBuilder {
addValueColumn( addValueColumn(
selectableMapping.getSelectionExpression(), selectableMapping.getSelectionExpression(),
selectableMapping.getWriteExpression(), selectableMapping.getWriteExpression(),
selectableMapping.getJdbcMapping() selectableMapping.getJdbcMapping(),
selectableMapping.isLob()
); );
} }

View File

@ -64,7 +64,7 @@ public class TableUpdateBuilderSkipped implements TableUpdateBuilder {
} }
@Override @Override
public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) { public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob) {
// nothing to do // nothing to do
} }

View File

@ -169,7 +169,7 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
table.getQualifiedTableName(), table.getQualifiedTableName(),
columnInformation.getTypeName().toLowerCase(Locale.ROOT), columnInformation.getTypeName().toLowerCase(Locale.ROOT),
JdbcTypeNameMapper.getTypeName( columnInformation.getTypeCode() ), JdbcTypeNameMapper.getTypeName( columnInformation.getTypeCode() ),
column.getSqlType().toLowerCase(Locale.ROOT), column.getSqlType( metadata ).toLowerCase(Locale.ROOT),
JdbcTypeNameMapper.getTypeName( column.getSqlTypeCode( metadata ) ) JdbcTypeNameMapper.getTypeName( column.getSqlTypeCode( metadata ) )
) )
); );

View File

@ -248,6 +248,24 @@ public interface JdbcType extends Serializable {
return false; return false;
} }
default boolean isLobOrLong() {
return isLobOrLong( getDdlTypeCode() );
}
static boolean isLobOrLong(int jdbcTypeCode) {
switch ( jdbcTypeCode ) {
case BLOB:
case CLOB:
case NCLOB:
case LONG32VARBINARY:
case LONG32VARCHAR:
case LONG32NVARCHAR: {
return true;
}
}
return false;
}
default boolean isNationalized() { default boolean isNationalized() {
return isNationalized( getDdlTypeCode() ); return isNationalized( getDdlTypeCode() );
} }

View File

@ -89,6 +89,11 @@ public interface DdlType extends Serializable {
@Deprecated(since = "6.3") @Deprecated(since = "6.3")
String getTypeName(Long size, Integer precision, Integer scale); String getTypeName(Long size, Integer precision, Integer scale);
default boolean isLob(Size size) {
// Let's be defensive and assume that LONG32 are LOBs as well
return JdbcType.isLobOrLong( getSqlTypeCode() );
}
/** /**
* Return the database type corresponding to the given {@link JdbcType} * Return the database type corresponding to the given {@link JdbcType}
* that may be used as a target type in casting operations using the SQL * that may be used as a target type in casting operations using the SQL

View File

@ -11,6 +11,8 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/** /**
* Descriptor for a SQL type. * Descriptor for a SQL type.
@ -19,6 +21,7 @@ import org.hibernate.dialect.Dialect;
*/ */
public class CapacityDependentDdlType extends DdlTypeImpl { public class CapacityDependentDdlType extends DdlTypeImpl {
private final LobKind lobKind;
private final TypeEntry[] typeEntries; private final TypeEntry[] typeEntries;
private CapacityDependentDdlType(Builder builder) { private CapacityDependentDdlType(Builder builder) {
@ -29,6 +32,7 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
builder.castTypeName, builder.castTypeName,
builder.dialect builder.dialect
); );
this.lobKind = builder.lobKind;
builder.typeEntries.sort( Comparator.naturalOrder() ); builder.typeEntries.sort( Comparator.naturalOrder() );
this.typeEntries = builder.typeEntries.toArray(new TypeEntry[0]); this.typeEntries = builder.typeEntries.toArray(new TypeEntry[0]);
} }
@ -73,8 +77,34 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
return super.getTypeName( size, precision, scale ); return super.getTypeName( size, precision, scale );
} }
@Override
public boolean isLob(Size size) {
if ( lobKind == LobKind.ALL_LOB ) {
return true;
}
final Long length = size.getLength();
if ( length != null && length > 0 ) {
for ( TypeEntry typeEntry : typeEntries ) {
if ( length <= typeEntry.capacity ) {
return false;
}
}
}
return lobKind == LobKind.BIGGEST_LOB;
}
public static Builder builder(int sqlTypeCode, String typeNamePattern, Dialect dialect) { public static Builder builder(int sqlTypeCode, String typeNamePattern, Dialect dialect) {
return builder( sqlTypeCode, typeNamePattern, typeNamePattern, dialect ); return builder(
sqlTypeCode,
JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE,
typeNamePattern,
typeNamePattern,
dialect
);
}
public static Builder builder(int sqlTypeCode, LobKind lobKind, String typeNamePattern, Dialect dialect) {
return builder( sqlTypeCode, lobKind, typeNamePattern, typeNamePattern, dialect );
} }
public static Builder builder( public static Builder builder(
@ -82,7 +112,22 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
String typeNamePattern, String typeNamePattern,
String castTypeName, String castTypeName,
Dialect dialect) { Dialect dialect) {
return new Builder( sqlTypeCode, typeNamePattern, null, castTypeName, dialect ); return builder(
sqlTypeCode,
JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE,
typeNamePattern,
castTypeName,
dialect
);
}
public static Builder builder(
int sqlTypeCode,
LobKind lobKind,
String typeNamePattern,
String castTypeName,
Dialect dialect) {
return builder( sqlTypeCode, lobKind, typeNamePattern, null, castTypeName, dialect );
} }
public static Builder builder( public static Builder builder(
@ -91,11 +136,29 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
String castTypeNamePattern, String castTypeNamePattern,
String castTypeName, String castTypeName,
Dialect dialect) { Dialect dialect) {
return new Builder( sqlTypeCode, typeNamePattern, castTypeNamePattern, castTypeName, dialect ); return builder(
sqlTypeCode,
JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE,
typeNamePattern,
castTypeNamePattern,
castTypeName,
dialect
);
}
public static Builder builder(
int sqlTypeCode,
LobKind lobKind,
String typeNamePattern,
String castTypeNamePattern,
String castTypeName,
Dialect dialect) {
return new Builder( sqlTypeCode, lobKind, typeNamePattern, castTypeNamePattern, castTypeName, dialect );
} }
public static class Builder { public static class Builder {
private final int sqlTypeCode; private final int sqlTypeCode;
private final LobKind lobKind;
private final String typeNamePattern; private final String typeNamePattern;
private final String castTypeNamePattern; private final String castTypeNamePattern;
private final String castTypeName; private final String castTypeName;
@ -104,11 +167,13 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
private Builder( private Builder(
int sqlTypeCode, int sqlTypeCode,
LobKind lobKind,
String typeNamePattern, String typeNamePattern,
String castTypeNamePattern, String castTypeNamePattern,
String castTypeName, String castTypeName,
Dialect dialect) { Dialect dialect) {
this.sqlTypeCode = sqlTypeCode; this.sqlTypeCode = sqlTypeCode;
this.lobKind = lobKind;
this.typeNamePattern = typeNamePattern; this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern; this.castTypeNamePattern = castTypeNamePattern;
this.castTypeName = castTypeName; this.castTypeName = castTypeName;
@ -140,4 +205,10 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
return Long.compare( capacity, o.capacity ); return Long.compare( capacity, o.capacity );
} }
} }
public enum LobKind {
BIGGEST_LOB,
ALL_LOB,
NONE
}
} }

View File

@ -23,6 +23,7 @@ import org.hibernate.type.descriptor.sql.DdlType;
public class DdlTypeImpl implements DdlType { public class DdlTypeImpl implements DdlType {
private final int sqlTypeCode; private final int sqlTypeCode;
private final boolean isLob;
private final String typeNamePattern; private final String typeNamePattern;
private final String castTypeNamePattern; private final String castTypeNamePattern;
private final String castTypeName; private final String castTypeName;
@ -43,11 +44,31 @@ public class DdlTypeImpl implements DdlType {
public DdlTypeImpl( public DdlTypeImpl(
int sqlTypeCode, int sqlTypeCode,
boolean isLob,
String typeNamePattern,
String castTypeName,
Dialect dialect) {
this( sqlTypeCode, isLob, typeNamePattern, null, castTypeName, dialect );
}
public DdlTypeImpl(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern, //optional, usually null
String castTypeName,
Dialect dialect) {
this( sqlTypeCode, JdbcType.isLob( sqlTypeCode ), typeNamePattern, castTypeNamePattern, castTypeName, dialect );
}
public DdlTypeImpl(
int sqlTypeCode,
boolean isLob,
String typeNamePattern, String typeNamePattern,
String castTypeNamePattern, //optional, usually null String castTypeNamePattern, //optional, usually null
String castTypeName, String castTypeName,
Dialect dialect) { Dialect dialect) {
this.sqlTypeCode = sqlTypeCode; this.sqlTypeCode = sqlTypeCode;
this.isLob = isLob;
this.typeNamePattern = typeNamePattern; this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern; this.castTypeNamePattern = castTypeNamePattern;
this.castTypeName = castTypeName; this.castTypeName = castTypeName;
@ -76,6 +97,11 @@ public class DdlTypeImpl implements DdlType {
return typeNamePattern; return typeNamePattern;
} }
@Override
public boolean isLob(Size size) {
return isLob;
}
@Override @Override
public String getTypeName(Long size, Integer precision, Integer scale) { public String getTypeName(Long size, Integer precision, Integer scale) {
return replace( typeNamePattern, size, precision, scale ); return replace( typeNamePattern, size, precision, scale );

View File

@ -25,7 +25,7 @@ public class RowIdType implements UserType<Object>{
@Override @Override
public int getSqlType() { public int getSqlType() {
return Types.JAVA_OBJECT; return Types.ROWID;
} }
public Class<Object> returnedClass() { public Class<Object> returnedClass() {