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 7cb740594e
commit 6c52aef28f
32 changed files with 505 additions and 106 deletions

View File

@ -174,7 +174,7 @@ ext {
//
// 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
'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' : ''
],
oracle_cloud_db19c : [

View File

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

View File

@ -185,23 +185,55 @@ public class DerbyLegacyDialect extends Dialect {
int varcharDdlTypeCapacity = 32_672;
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 ) )
.build()
);
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 ) )
.build()
);
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 ) )
.build()
);
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( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build()
@ -209,13 +241,29 @@ public class DerbyLegacyDialect extends Dialect {
// This is the maximum size for the CHAR datatype on Derby
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( getMaxVarcharLength(), columnType( VARCHAR ) )
.build()
);
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( getMaxVarcharLength(), columnType( NVARCHAR ) )
.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.CLOB;
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.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
@ -113,7 +114,15 @@ public class MimerSQLDialect extends Dialect {
//Mimer CHARs are ASCII!!
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 ) )
.build()
);

View File

@ -311,7 +311,7 @@ public class MySQLLegacyDialect extends Dialect {
final CapacityDependentDdlType.Builder varcharBuilder = CapacityDependentDdlType.builder(
VARCHAR,
columnType( CLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( CLOB ),
"char",
this
)
@ -324,7 +324,7 @@ public class MySQLLegacyDialect extends Dialect {
final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder(
NVARCHAR,
columnType( NCLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( NCLOB ),
"char",
this
)
@ -337,7 +337,7 @@ public class MySQLLegacyDialect extends Dialect {
final CapacityDependentDdlType.Builder varbinaryBuilder = CapacityDependentDdlType.builder(
VARBINARY,
columnType( BLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( BLOB ),
"binary",
this
)

View File

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

View File

@ -182,23 +182,55 @@ public class DerbyDialect extends Dialect {
int varcharDdlTypeCapacity = 32_672;
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 ) )
.build()
);
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 ) )
.build()
);
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 ) )
.build()
);
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( varcharDdlTypeCapacity, columnType( VARBINARY ) )
.build()
@ -206,13 +238,29 @@ public class DerbyDialect extends Dialect {
// This is the maximum size for the CHAR datatype on Derby
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( getMaxVarcharLength(), columnType( VARCHAR ) )
.build()
);
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( getMaxVarcharLength(), columnType( NVARCHAR ) )
.build()

View File

@ -440,10 +440,34 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32NVARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARBINARY ) );
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) {
return new DdlTypeImpl( sqlTypeCode, columnType( sqlTypeCode ), castType( sqlTypeCode ), this );
return new DdlTypeImpl(
sqlTypeCode,
isLob( sqlTypeCode ),
columnType( sqlTypeCode ),
castType( sqlTypeCode ),
this
);
}
/**
@ -457,6 +481,11 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
private CapacityDependentDdlType.Builder sqlTypeBuilder(int sqlTypeCode, int biggestSqlTypeCode, int castTypeCode) {
return CapacityDependentDdlType.builder(
sqlTypeCode,
isLob( sqlTypeCode )
? CapacityDependentDdlType.LobKind.ALL_LOB
: isLob( biggestSqlTypeCode )
? CapacityDependentDdlType.LobKind.BIGGEST_LOB
: CapacityDependentDdlType.LobKind.NONE,
columnType( biggestSqlTypeCode ),
castType( castTypeCode ),
this
@ -504,6 +533,9 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
*/
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case ROWID:
return "rowid";
case BOOLEAN:
return "boolean";

View File

@ -316,7 +316,7 @@ public class MySQLDialect extends Dialect {
final CapacityDependentDdlType.Builder varcharBuilder = CapacityDependentDdlType.builder(
VARCHAR,
columnType( CLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( CLOB ),
"char",
this
)
@ -329,7 +329,7 @@ public class MySQLDialect extends Dialect {
final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder(
NVARCHAR,
columnType( NCLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( NCLOB ),
"char",
this
)
@ -342,7 +342,7 @@ public class MySQLDialect extends Dialect {
final CapacityDependentDdlType.Builder varbinaryBuilder = CapacityDependentDdlType.builder(
VARBINARY,
columnType( BLOB ),
CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( BLOB ),
"binary",
this
)

View File

@ -31,6 +31,8 @@ import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
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.spi.TypeConfiguration;
@ -58,6 +60,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private boolean unique;
private String sqlTypeName;
private Integer sqlTypeCode;
private boolean sqlTypeLob;
private boolean quoted;
int uniqueInteger;
private String comment;
@ -270,11 +273,34 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private String getSqlTypeName(DdlTypeRegistry ddlTypeRegistry, Dialect dialect, Mapping mapping) {
if ( sqlTypeName == null ) {
try {
final Type type = getValue().getType();
sqlTypeName = isArray( type )
? dialect.getArrayTypeName( getArrayElementTypeName( dialect, ddlTypeRegistry, getArrayElementType( type ) ) )
: ddlTypeRegistry.getTypeName( getSqlTypeCode( mapping ), getColumnSize( dialect, mapping ) );
try {
if ( isArray( type ) ) {
sqlTypeName = dialect.getArrayTypeName( getArrayElementTypeName( dialect, ddlTypeRegistry, getArrayElementType( type ) ) );
sqlTypeLob = false;
}
else {
final int typeCode = getSqlTypeCode( mapping );
final DdlType descriptor = ddlTypeRegistry.getDescriptor( typeCode );
if ( descriptor == null ) {
throw new MappingException(
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 )
)
);
}
final Size size = getColumnSize( dialect, mapping );
sqlTypeName = ddlTypeRegistry.getTypeName( typeCode, size );
sqlTypeLob = descriptor.isLob( size );
}
}
catch ( MappingException cause ) {
throw cause;
}
catch ( Exception cause ) {
throw new MappingException(
@ -467,6 +493,10 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
sqlTypeName = typeName;
}
public boolean isSqlTypeLob() {
return sqlTypeLob;
}
public void setUnique(boolean unique) {
this.unique = unique;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -502,7 +502,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
false,
false,
creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
final BasicAttributeMapping keyModelPart = BasicAttributeMapping.withSelectableMapping(
@ -538,7 +539,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
elementBootDescriptor.getColumnInsertability(),
elementBootDescriptor.getColumnUpdateability(),
creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
return new EmbeddedForeignKeyDescriptor(
@ -676,7 +678,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
fkBootDescriptorSource.getColumnInsertability(),
fkBootDescriptorSource.getColumnUpdateability(),
creationProcess.getCreationContext().getDialect(),
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
return foreignKeyDescriptor.withKeySelectionMapping(
declaringType,
@ -718,7 +721,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
columnUpdateable,
fkValue.isPartitionKey(),
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

View File

@ -194,6 +194,7 @@ public class MappingModelCreationHelper {
Long length,
Integer precision,
Integer scale,
boolean isLob,
boolean nullable,
boolean insertable,
boolean updateable,
@ -240,6 +241,7 @@ public class MappingModelCreationHelper {
length,
precision,
scale,
isLob,
nullable,
insertable,
updateable,
@ -509,7 +511,8 @@ public class MappingModelCreationHelper {
index.isColumnUpdateable( 0 ),
false,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
@ -562,7 +565,8 @@ public class MappingModelCreationHelper {
index.isColumnUpdateable( 0 ),
false,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
@ -773,7 +777,8 @@ public class MappingModelCreationHelper {
bootValueMappingKey.isColumnUpdateable( 0 ),
false,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
final SimpleForeignKeyDescriptor keyDescriptor = new SimpleForeignKeyDescriptor(
@ -949,7 +954,8 @@ public class MappingModelCreationHelper {
value.isColumnUpdateable( i ),
((SimpleValue) value).isPartitionKey(),
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
i++;
}
@ -964,7 +970,8 @@ public class MappingModelCreationHelper {
value.isColumnUpdateable( 0 ),
((SimpleValue) value).isPartitionKey(),
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
}
@ -1111,7 +1118,8 @@ public class MappingModelCreationHelper {
insertable,
updateable,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
}
else {
@ -1135,7 +1143,8 @@ public class MappingModelCreationHelper {
insertable,
updateable,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
}
if ( inverse ) {
@ -1315,7 +1324,8 @@ public class MappingModelCreationHelper {
updatable,
false,
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
return new BasicValuedCollectionPart(
collectionDescriptor,
@ -1412,7 +1422,8 @@ public class MappingModelCreationHelper {
basicElement.isPartitionKey(),
true, // element collection does not support null elements
dialect,
creationProcess.getSqmFunctionRegistry()
creationProcess.getSqmFunctionRegistry(),
creationProcess.getCreationContext()
);
return new BasicValuedCollectionPart(
collectionDescriptor,

View File

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

View File

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

View File

@ -5037,7 +5037,7 @@ public abstract class AbstractEntityPersister
scale = null;
}
else {
columnDefinition = column.getSqlType();
columnDefinition = column.getSqlType( modelCreationProcess.getCreationContext().getMetadata() );
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
@ -5214,7 +5214,7 @@ public abstract class AbstractEntityPersister
}
else {
Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 );
columnDefinition = column.getSqlType();
columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
@ -5273,7 +5273,7 @@ public abstract class AbstractEntityPersister
bootModelRootEntityDescriptor.getVersion().getName(),
entityPersister.getTableName(),
column.getText( dialect ),
column.getSqlType(),
column.getSqlType( creationProcess.getCreationContext().getMetadata() ),
column.getLength(),
column.getPrecision(),
column.getScale(),
@ -5318,10 +5318,11 @@ public abstract class AbstractEntityPersister
false,
null,
"?",
column.getSqlType(),
column.getSqlType( creationProcess.getCreationContext().getMetadata() ),
column.getLength(),
column.getPrecision(),
column.getScale(),
column.isSqlTypeLob(),
column.isNullable(),
value.isColumnInsertable( 0 ),
value.isColumnUpdateable( 0 ),
@ -5340,6 +5341,7 @@ public abstract class AbstractEntityPersister
final Long length;
final Integer precision;
final Integer scale;
final boolean isLob;
final boolean nullable;
if ( value instanceof DependantValue ) {
@ -5348,10 +5350,11 @@ public abstract class AbstractEntityPersister
customReadExpr = null;
customWriteExpr = "?";
Column column = value.getColumns().get( 0 );
columnDefinition = column.getSqlType();
columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() );
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
isLob = column.isSqlTypeLob();
nullable = column.isNullable();
}
else {
@ -5374,11 +5377,12 @@ public abstract class AbstractEntityPersister
);
customWriteExpr = selectable.getWriteExpr( (JdbcMapping) attrType, creationContext.getDialect() );
Column column = value.getColumns().get( 0 );
columnDefinition = column.getSqlType();
columnDefinition = column.getSqlType( creationContext.getMetadata() );
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
nullable = column.isNullable();
isLob = column.isSqlTypeLob();
}
else {
final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ];
@ -5391,6 +5395,7 @@ public abstract class AbstractEntityPersister
precision = null;
scale = null;
nullable = true;
isLob = false;
}
}
@ -5412,6 +5417,7 @@ public abstract class AbstractEntityPersister
length,
precision,
scale,
isLob,
nullable,
value.isColumnInsertable( 0 ),
value.isColumnUpdateable( 0 ),

View File

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

View File

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

View File

@ -70,10 +70,10 @@ public abstract class AbstractTableInsertBuilder
}
@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 );
if ( jdbcMapping.getJdbcType().isLob() && getJdbcServices().getDialect().forceLobAsLastValue() ) {
if ( isLob && getJdbcServices().getDialect().forceLobAsLastValue() ) {
if ( lobValueBindingList == null ) {
lobValueBindingList = new ArrayList<>();
}

View File

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

View File

@ -19,7 +19,13 @@ public interface ColumnValuesTableMutationBuilder {
/**
* 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
@ -28,7 +34,8 @@ public interface ColumnValuesTableMutationBuilder {
addValueColumn(
selectableMapping.getSelectionExpression(),
selectableMapping.getWriteExpression(),
selectableMapping.getJdbcMapping()
selectableMapping.getJdbcMapping(),
selectableMapping.isLob()
);
}

View File

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

View File

@ -238,6 +238,24 @@ public interface JdbcType extends Serializable {
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() {
return isNationalized( getDdlTypeCode() );
}

View File

@ -64,6 +64,11 @@ public interface DdlType extends Serializable {
*/
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}
* 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 org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* Descriptor for a SQL type.
@ -19,6 +21,7 @@ import org.hibernate.dialect.Dialect;
*/
public class CapacityDependentDdlType extends DdlTypeImpl {
private final LobKind lobKind;
private final TypeEntry[] typeEntries;
private CapacityDependentDdlType(Builder builder) {
@ -26,8 +29,10 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
builder.sqlTypeCode,
builder.typeNamePattern,
builder.castTypeNamePattern,
builder.castTypeName,
builder.dialect
);
this.lobKind = builder.lobKind;
builder.typeEntries.sort( Comparator.naturalOrder() );
this.typeEntries = builder.typeEntries.toArray(new TypeEntry[0]);
}
@ -71,33 +76,106 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
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) {
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(
int sqlTypeCode,
String typeNamePattern,
String castTypeName,
Dialect 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(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern,
String castTypeName,
Dialect dialect) {
return new Builder( sqlTypeCode, typeNamePattern, castTypeNamePattern, 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 {
private final int sqlTypeCode;
private final LobKind lobKind;
private final String typeNamePattern;
private final String castTypeNamePattern;
private final String castTypeName;
private final Dialect dialect;
private final List<TypeEntry> typeEntries;
private Builder(
int sqlTypeCode,
LobKind lobKind,
String typeNamePattern,
String castTypeNamePattern,
String castTypeName,
Dialect dialect) {
this.sqlTypeCode = sqlTypeCode;
this.lobKind = lobKind;
this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern;
this.castTypeName = castTypeName;
this.dialect = dialect;
this.typeEntries = new ArrayList<>();
}
@ -126,4 +204,10 @@ public class CapacityDependentDdlType extends DdlTypeImpl {
return Long.compare( capacity, o.capacity );
}
}
public enum LobKind {
BIGGEST_LOB,
ALL_LOB,
NONE
}
}

View File

@ -10,6 +10,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.CharacterJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.DdlType;
@ -22,26 +23,59 @@ import org.hibernate.type.descriptor.sql.DdlType;
public class DdlTypeImpl implements DdlType {
private final int sqlTypeCode;
private final boolean isLob;
private final String typeNamePattern;
private final String castTypeNamePattern;
private final String castTypeName;
private final boolean castTypeNameIsStatic;
private final Dialect dialect;
public DdlTypeImpl(int sqlTypeCode, String typeNamePattern, Dialect dialect) {
this( sqlTypeCode, typeNamePattern, typeNamePattern, dialect );
this( sqlTypeCode, typeNamePattern, typeNamePattern, typeNamePattern, dialect );
}
public DdlTypeImpl(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern,
String castTypeName,
Dialect dialect) {
this( sqlTypeCode, typeNamePattern, null, castTypeName, dialect );
}
public DdlTypeImpl(
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 castTypeNamePattern, //optional, usually null
String castTypeName,
Dialect dialect) {
this.sqlTypeCode = sqlTypeCode;
this.isLob = isLob;
this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern;
this.castTypeNameIsStatic = !castTypeNamePattern.contains( "$s" )
&& !castTypeNamePattern.contains( "$l" )
&& !castTypeNamePattern.contains( "$p" );
this.castTypeName = castTypeName;
this.castTypeNameIsStatic =
!castTypeName.contains( "$s" )
&& !castTypeName.contains( "$p" )
&& !castTypeName.contains( "$l" );
this.dialect = dialect;
}
@ -58,7 +92,7 @@ public class DdlTypeImpl implements DdlType {
final int parenEnd = typeNamePattern.lastIndexOf( ')' );
return parenEnd + 1 == typeNamePattern.length()
? typeNamePattern.substring( 0, paren )
: ( typeNamePattern.substring( 0, paren ) + typeNamePattern.substring( parenEnd + 1 ) );
: typeNamePattern.substring( 0, paren ) + typeNamePattern.substring( parenEnd + 1 );
}
return typeNamePattern;
}
@ -68,6 +102,11 @@ public class DdlTypeImpl implements DdlType {
return typeNamePattern;
}
@Override
public boolean isLob(Size size) {
return isLob;
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
return replace( typeNamePattern, size, precision, scale );
@ -84,38 +123,40 @@ public class DdlTypeImpl implements DdlType {
//needed for cast(x as BigInteger(p))
scale = javaType.getDefaultSqlScale( dialect, jdbcType );
}
return castTypeNamePattern == null
? getTypeName( length, precision, scale )
: replace( castTypeNamePattern, length, precision, scale );
}
return getTypeName( length, precision, scale );
}
@Override
public String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType) {
if ( castTypeNameIsStatic ) {
return castTypeNamePattern;
if ( javaType instanceof CharacterJavaType && jdbcType.isString() ) {
// nasty special case for casting to Character
return getCastTypeName( jdbcType, javaType, 1L, null, null );
}
Long length = null;
Integer precision = null;
Integer scale = null;
else if ( castTypeNameIsStatic ) {
return castTypeName;
}
else {
final Size size = dialect.getSizeStrategy()
.resolveSize( jdbcType, javaType, null, null, defaultLength( jdbcType ) );
return replace( castTypeName, size.getLength(), size.getPrecision(), size.getScale() );
}
}
//TODO: move this to JdbcType??
private Long defaultLength(JdbcType jdbcType) {
switch ( jdbcType.getDdlTypeCode() ) {
case SqlTypes.VARCHAR:
length = (long) dialect.getMaxVarcharLength();
break;
return (long) dialect.getMaxVarcharLength();
case SqlTypes.NVARCHAR:
length = (long) dialect.getMaxNVarcharLength();
break;
return (long) dialect.getMaxNVarcharLength();
case SqlTypes.VARBINARY:
length = (long) dialect.getMaxVarbinaryLength();
break;
return (long) dialect.getMaxVarbinaryLength();
default:
return null;
}
final Size size = dialect.getSizeStrategy().resolveSize(
jdbcType,
javaType,
precision,
scale,
length
);
return replace( castTypeNamePattern, size.getLength(), size.getPrecision(), size.getScale() );
}
/**

View File

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