HHH-16125 Oracle array support using varray types

This commit is contained in:
Gavin 2023-04-29 17:00:47 +02:00 committed by Gavin King
parent 783e0772e6
commit 07268d6568
32 changed files with 364 additions and 162 deletions

View File

@ -70,6 +70,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -294,7 +295,7 @@ public class CockroachLegacyDialect extends Dialect {
jdbcTypeRegistry.getTypeConfiguration(),
this,
jdbcTypeRegistry.getDescriptor( sqlTypeCode ),
null
ColumnTypeInformation.EMPTY
);
}
}

View File

@ -746,11 +746,8 @@ public class OracleLegacyDialect extends Dialect {
}
@Override
public String getArrayTypeName(String elementTypeName) {
// Return null to signal that there is no array type since Oracle only has named array types
// TODO: discuss if it makes sense to parse a config parameter to a map which we can query here
// e.g. `hibernate.oracle.array_types=numeric(10,0)=intarray,...`
return null;
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return javaElementTypeName + "Array";
}
@Override

View File

@ -85,6 +85,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
@ -346,7 +347,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
jdbcTypeRegistry.getTypeConfiguration(),
this,
jdbcTypeRegistry.getDescriptor( sqlTypeCode ),
null
ColumnTypeInformation.EMPTY
);
}
}

View File

@ -695,7 +695,7 @@ public class MetadataBuildingProcess {
ddlTypeRegistry.addDescriptorIfAbsent(
new DdlTypeImpl(
SqlTypes.GEOGRAPHY,
geometryType.getTypeName( null, null, null ),
geometryType.getTypeName( (Long) null, (Integer) null, (Integer) null ),
dialect
)
);

View File

@ -57,6 +57,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -313,7 +314,7 @@ public class CockroachDialect extends Dialect {
jdbcTypeRegistry.getTypeConfiguration(),
this,
jdbcTypeRegistry.getDescriptor( sqlTypeCode ),
null
ColumnTypeInformation.EMPTY
);
}
}

View File

@ -152,6 +152,7 @@ import org.hibernate.sql.model.internal.OptionalTableUpdate;
import org.hibernate.sql.model.jdbc.OptionalTableUpdateOperation;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.tool.schema.internal.HibernateSchemaManagementTool;
import org.hibernate.tool.schema.internal.StandardAuxiliaryDatabaseObjectExporter;
@ -188,6 +189,7 @@ import org.hibernate.type.descriptor.jdbc.TimeUtcAsOffsetTimeJdbcType;
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsJdbcTimestampJdbcType;
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsOffsetDateTimeJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
@ -441,6 +443,10 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32NVARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARBINARY ) );
if ( supportsStandardArrays() ) {
ddlTypeRegistry.addDescriptor( new ArrayDdlTypeImpl( this ) );
}
}
private DdlTypeImpl simpleSqlType(int sqlTypeCode) {
@ -701,7 +707,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
jdbcTypeRegistry.getTypeConfiguration(),
this,
jdbcTypeRegistry.getDescriptor( sqlTypeCode ),
null
ColumnTypeInformation.EMPTY
);
}
}
@ -4183,7 +4189,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
*
* @since 6.1
*/
public String getArrayTypeName(String elementTypeName) {
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return supportsStandardArrays() ? elementTypeName + " array" : null;
}
@ -4917,6 +4923,8 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
}
switch ( ddlTypeCode ) {
case SqlTypes.ARRAY:
break;
case SqlTypes.BIT:
case SqlTypes.CHAR:
case SqlTypes.NCHAR:
@ -4965,11 +4973,10 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
case SqlTypes.DECIMAL:
case SqlTypes.INTERVAL_SECOND:
size.setPrecision( javaType.getDefaultSqlPrecision( Dialect.this, jdbcType ) );
size.setScale( javaType.getDefaultSqlScale( Dialect.this, jdbcType ) );
break;
}
size.setScale( javaType.getDefaultSqlScale( Dialect.this, jdbcType ) );
if ( precision != null ) {
size.setPrecision( precision );
}

View File

@ -1295,8 +1295,8 @@ public class DialectDelegateWrapper extends Dialect {
}
@Override
public String getArrayTypeName(String elementTypeName) {
return wrapped.getArrayTypeName( elementTypeName );
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return wrapped.getArrayTypeName( javaElementTypeName, elementTypeName );
}
@Override

View File

@ -133,13 +133,25 @@ public class MySQLDialect extends Dialect {
Integer scale,
Long length) {
switch ( jdbcType.getDdlTypeCode() ) {
case Types.BIT:
case BIT:
// MySQL allows BIT with a length up to 64 (less the default length 255)
if ( length != null ) {
return Size.length( Math.min( Math.max( length, 1 ), 64 ) );
}
case FLOAT:
case DOUBLE:
case REAL:
//MySQL doesn't let you cast to DOUBLE/FLOAT
//but don't just return 'decimal' because
//the default scale is 0 (no decimal places)
Size size = super.resolveSize( jdbcType, javaType, precision, scale, length );
//cast() on MySQL does not behave sensibly if
//we set scale > 20
size.setScale( Math.min( size.getPrecision(), 20 ) );
return size;
default:
return super.resolveSize( jdbcType, javaType, precision, scale, length );
}
return super.resolveSize( jdbcType, javaType, precision, scale, length );
}
};

View File

@ -11,12 +11,14 @@ import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import java.util.Locale;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.NamedAuxiliaryDatabaseObject;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
@ -25,11 +27,13 @@ import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.ObjectJdbcType;
import org.hibernate.type.spi.TypeConfiguration;
import oracle.jdbc.OracleConnection;
import static java.sql.Types.ARRAY;
import static java.util.Collections.emptySet;
/**
* Descriptor for {@link Types#ARRAY ARRAY} handling.
*
@ -41,63 +45,61 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
private final String typeName;
public OracleArrayJdbcType() {
super( ObjectJdbcType.INSTANCE );
this.typeName = null;
this( null, null );
}
private OracleArrayJdbcType(String typeName, JdbcType elementJdbcType) {
public OracleArrayJdbcType(JdbcType elementJdbcType, String typeName) {
super( elementJdbcType );
this.typeName = typeName;
}
@Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaTypeDescriptor) {
// No array literal support
return null;
}
@Override
public JdbcType resolveType(
TypeConfiguration typeConfiguration,
Dialect dialect,
JdbcType elementType,
ColumnTypeInformation columnTypeInformation) {
public JdbcType resolveType(TypeConfiguration typeConfiguration, Dialect dialect, BasicType<?> elementType, ColumnTypeInformation columnTypeInformation) {
String typeName = columnTypeInformation.getTypeName();
if ( typeName == null || typeName.isBlank() ) {
typeName = dialect.getArrayTypeName(
typeConfiguration.getDdlTypeRegistry().getTypeName(
elementType.getDdlTypeCode(),
dialect
)
);
typeName = getTypeName( elementType.getJavaTypeDescriptor(), dialect );
}
if ( typeName == null ) {
// Fallback to XML type for the representation of arrays as the native JSON type was only introduced in 21
// Also, use the XML type if the Oracle JDBC driver classes are not visible
return typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.SQLXML );
}
return new OracleArrayJdbcType( typeName, elementType );
// if ( typeName == null ) {
// // Fallback to XML type for the representation of arrays as the native JSON type was only introduced in 21
// // Also, use the XML type if the Oracle JDBC driver classes are not visible
// return typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.SQLXML );
// }
return new OracleArrayJdbcType( elementType.getJdbcType(), typeName );
}
@Override
public JdbcType resolveType(TypeConfiguration typeConfiguration, Dialect dialect, JdbcType elementType, ColumnTypeInformation columnTypeInformation) {
// a bit wrong!
return new OracleArrayJdbcType( elementType, columnTypeInformation.getTypeName() );
}
@Override
public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
//noinspection unchecked
final BasicPluralJavaType<X> containerJavaType = (BasicPluralJavaType<X>) javaTypeDescriptor;
return new BasicBinder<X>( javaTypeDescriptor, this ) {
return new BasicBinder<>( javaTypeDescriptor, this ) {
private String typeName(WrapperOptions options) {
return ( typeName == null ? getTypeName( options, containerJavaType ) : typeName )
.toUpperCase(Locale.ROOT);
}
@Override
protected void doBindNull(PreparedStatement st, int index, WrapperOptions options) throws SQLException {
st.setNull( index, Types.ARRAY, typeName );
st.setNull( index, ARRAY, typeName( options ) );
}
@Override
protected void doBindNull(CallableStatement st, String name, WrapperOptions options) throws SQLException {
st.setNull( name, Types.ARRAY, typeName );
st.setNull( name, ARRAY, typeName( options ) );
}
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
final java.sql.Array arr = getArray( value, containerJavaType, options );
st.setArray( index, arr );
st.setArray( index, getArray( value, containerJavaType, options ) );
}
@Override
@ -105,7 +107,7 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
throws SQLException {
final java.sql.Array arr = getArray( value, containerJavaType, options );
try {
st.setObject( name, arr, Types.ARRAY );
st.setObject( name, arr, ARRAY );
}
catch (SQLException ex) {
throw new HibernateException( "JDBC driver does not support named parameters for setArray. Use positional.", ex );
@ -122,12 +124,13 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
0
).getClass();
final Object[] objects = javaTypeDescriptor.unwrap( value, arrayClass, options );
final String arrayTypeName = typeName( options ).toUpperCase(Locale.ROOT);
final SharedSessionContractImplementor session = options.getSession();
final OracleConnection oracleConnection = session.getJdbcCoordinator().getLogicalConnection().getPhysicalConnection()
final OracleConnection oracleConnection = options.getSession()
.getJdbcCoordinator().getLogicalConnection().getPhysicalConnection()
.unwrap( OracleConnection.class );
try {
return oracleConnection.createOracleArray( typeName, objects );
return oracleConnection.createOracleArray( arrayTypeName, objects );
}
catch (Exception e) {
throw new HibernateException( "Couldn't create a java.sql.Array", e );
@ -136,22 +139,54 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
};
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
private static String getTypeName(WrapperOptions options, BasicPluralJavaType<?> containerJavaType) {
Dialect dialect = options.getSessionFactory().getJdbcServices().getDialect();
return getTypeName( containerJavaType.getElementJavaType(), dialect );
}
OracleArrayJdbcType that = (OracleArrayJdbcType) o;
return Objects.equals( typeName, that.typeName );
private static String getTypeName(JavaType<?> elementJavaType, Dialect dialect) {
return dialect.getArrayTypeName(
elementJavaType.getJavaTypeClass().getSimpleName(),
null // not needed by OracleDialect.getArrayTypeName()
);
}
@Override
public int hashCode() {
return typeName != null ? typeName.hashCode() : 0;
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
final Dialect dialect = database.getDialect();
final BasicPluralJavaType<?> pluralJavaType = (BasicPluralJavaType<?>) javaType;
final String elementTypeName = typeName==null
? getTypeName( pluralJavaType.getElementJavaType(), dialect )
: typeName;
final String elementType =
typeConfiguration.getDdlTypeRegistry().getTypeName(
getElementJdbcType().getDdlTypeCode(),
dialect.getSizeStrategy().resolveSize(
getElementJdbcType(),
pluralJavaType.getElementJavaType(),
columnSize.getPrecision(),
columnSize.getScale(),
columnSize.getLength()
)
);
final String[] create = new String[] { "create or replace type " + elementTypeName + " as varying array(255) of " + elementType };
final String[] drop = new String[] {
// "drop type " + elementTypeName
};
database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject( elementTypeName, database.getDefaultNamespace(), create, drop, emptySet(), true )
);
}
// @Override
// public String getExtraCreateTableInfo(JavaType<?> javaType, String columnName, String tableName, Database database) {
// final Dialect dialect = database.getDialect();
// final BasicPluralJavaType<?> pluralJavaType = (BasicPluralJavaType<?>) javaType;
// String elementTypeName = getTypeName( pluralJavaType.getElementJavaType(), dialect );
// return " nested table " + columnName + " store as " + tableName + columnName + elementTypeName;
// }
}

View File

@ -87,6 +87,7 @@ import org.hibernate.type.descriptor.jdbc.NullJdbcType;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.OracleJsonBlobJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
@ -685,6 +686,8 @@ public class OracleDialect extends Dialect {
else if ( getVersion().isSameOrAfter( 12 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "blob", this ) );
}
ddlTypeRegistry.addDescriptor( new ArrayDdlTypeImpl( this ) );
}
@Override
@ -781,11 +784,8 @@ public class OracleDialect extends Dialect {
}
@Override
public String getArrayTypeName(String elementTypeName) {
// Return null to signal that there is no array type since Oracle only has named array types
// TODO: discuss if it makes sense to parse a config parameter to a map which we can query here
// e.g. `hibernate.oracle.array_types=numeric(10,0)=intarray,...`
return null;
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return javaElementTypeName + "Array";
}
@Override

View File

@ -8,7 +8,6 @@ package org.hibernate.dialect;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.Stack;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
@ -21,7 +20,6 @@ import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.ast.tree.cte.CteMaterialization;
import org.hibernate.sql.ast.tree.expression.AggregateColumnWriteExpression;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
@ -31,7 +29,6 @@ import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
import org.hibernate.sql.ast.tree.expression.Summarization;
import org.hibernate.sql.ast.tree.from.FunctionTableReference;
import org.hibernate.sql.ast.tree.from.NamedTableReference;
import org.hibernate.sql.ast.tree.from.QueryPartTableReference;
import org.hibernate.sql.ast.tree.from.UnionTableGroup;
import org.hibernate.sql.ast.tree.from.ValuesTableReference;
@ -442,12 +439,42 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends SqlAstTrans
rhs.accept( this );
appendSql( ')' );
break;
case SqlTypes.ARRAY:
switch ( operator ) {
case DISTINCT_FROM:
appendSql( "decode(" );
arrayToString( lhs );
appendSql( ',' );
arrayToString( rhs );
appendSql( ",0,1)=1" );
break;
case NOT_DISTINCT_FROM:
appendSql( "decode(" );
arrayToString( lhs );
appendSql( ',' );
arrayToString( rhs );
appendSql( ",0,1)=0" );
break;
default:
arrayToString( lhs );
appendSql( operator.sqlText() );
arrayToString( rhs );
}
break;
default:
renderComparisonEmulateDecode( lhs, operator, rhs );
break;
}
}
private void arrayToString(Expression expression) {
appendSql("case when ");
expression.accept( this );
appendSql(" is not null then (select listagg(column_value||',')||';' from table(");
expression.accept( this );
appendSql(")) else null end");
}
@Override
protected void renderSelectTupleComparison(
List<SqlSelection> lhsExpressions,

View File

@ -74,6 +74,7 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.internal.OptionalTableUpdate;
import org.hibernate.sql.model.jdbc.OptionalTableUpdateOperation;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
@ -246,7 +247,7 @@ public class PostgreSQLDialect extends Dialect {
// Prefer jsonb if possible
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "jsonb", this ) );
ddlTypeRegistry.addDescriptor( NAMED_ENUM, new NamedNativeEnumDdlTypeImpl( this ) );
ddlTypeRegistry.addDescriptor( new NamedNativeEnumDdlTypeImpl( this ) );
}
@Override
@ -325,7 +326,7 @@ public class PostgreSQLDialect extends Dialect {
jdbcTypeRegistry.getTypeConfiguration(),
this,
jdbcTypeRegistry.getDescriptor( sqlTypeCode ),
null
ColumnTypeInformation.EMPTY
);
}
}
@ -828,6 +829,7 @@ public class PostgreSQLDialect extends Dialect {
@Override
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
// TODO: adapt this to handle named enum types!
// Workaround for postgres bug #1453
return "null::" + typeConfiguration.getDdlTypeRegistry().getDescriptor( sqlType ).getRawTypeName();
}

View File

@ -8,7 +8,7 @@ package org.hibernate.dialect;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.NamedAuxiliaryDatabaseObject;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
@ -17,6 +17,7 @@ import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
@ -114,15 +115,19 @@ public class PostgreSQLEnumJdbcType implements JdbcType {
}
@Override
public void addAuxiliaryDatabaseObjects(JavaType<?> javaType, InFlightMetadataCollector metadataCollector) {
Database database = metadataCollector.getDatabase();
Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
String name = enumClass.getSimpleName();
String[] create = database.getDialect().getCreateEnumTypeCommand( enumClass );
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
final Dialect dialect = database.getDialect();
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
final String enumTypeName = enumClass.getSimpleName();
final String[] create = dialect.getCreateEnumTypeCommand( enumClass );
if ( create != null ) {
String[] drop = database.getDialect().getDropEnumTypeCommand( enumClass );
final String[] drop = dialect.getDropEnumTypeCommand( enumClass );
database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject( name, database.getDefaultNamespace(), create, drop, emptySet(), true )
new NamedAuxiliaryDatabaseObject( enumTypeName, database.getDefaultNamespace(), create, drop, emptySet(), true )
);
}
}

View File

@ -188,7 +188,7 @@ public class SpannerDialect extends Dialect {
}
@Override
public String getArrayTypeName(String elementTypeName) {
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return "ARRAY<" + elementTypeName + ">";
}

View File

@ -19,7 +19,6 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
import org.hibernate.type.spi.TypeConfiguration;

View File

@ -31,6 +31,7 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
@ -314,19 +315,38 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
}
final Selectable selectable = getColumn();
final Size size;
if ( selectable instanceof Column ) {
resolveColumn( (Column) selectable, getDialect() );
Column column = (Column) selectable;
resolveColumn( column, getDialect() );
size = column.calculateColumnSize( getDialect(), getBuildingContext().getMetadataCollector() );
}
else {
size = Size.nil();
}
resolution.getJdbcType()
.addAuxiliaryDatabaseObjects(
resolution.getRelationalJavaType(),
getBuildingContext().getMetadataCollector()
size,
getBuildingContext().getMetadataCollector().getDatabase(),
getTypeConfiguration()
);
return resolution;
}
@Override
public String getExtraCreateTableInfo() {
return resolution.getJdbcType()
.getExtraCreateTableInfo(
resolution.getRelationalJavaType(),
getColumn().getText(),
getTable().getName(),
getBuildingContext().getMetadataCollector().getDatabase()
);
}
@Override
public Dialect getDialect() {
return getMetadata().getDatabase().getDialect();

View File

@ -13,7 +13,6 @@ import java.util.Locale;
import java.util.Objects;
import org.hibernate.AssertionFailure;
import org.hibernate.Incubating;
import org.hibernate.MappingException;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.TruthValue;
@ -26,12 +25,9 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.sql.Template;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.BasicPluralType;
import org.hibernate.type.BasicType;
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.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
@ -272,11 +268,11 @@ 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 )
//TODO: remove the special case for array types, this should be handled by the DdlType!
? dialect.getArrayTypeName( getArrayElementTypeName( dialect, ddlTypeRegistry, getArrayElementType( type ) ) )
: ddlTypeRegistry.getTypeName( getSqlTypeCode( mapping ), getColumnSize( dialect, mapping ), getUnderlyingType( mapping, type, typeIndex ) );
sqlTypeName = ddlTypeRegistry.getTypeName(
getSqlTypeCode( mapping ),
getColumnSize( dialect, mapping ),
getUnderlyingType( mapping, getValue().getType(), typeIndex )
);
}
catch ( Exception cause ) {
throw new MappingException(
@ -314,29 +310,6 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
}
}
private String getArrayElementTypeName(Dialect dialect, DdlTypeRegistry ddlTypeRegistry, BasicType<?> elementType) {
return ddlTypeRegistry.getTypeName(
elementType.getJdbcType().getDdlTypeCode(),
dialect.getSizeStrategy().resolveSize(
elementType.getJdbcMapping().getJdbcType(),
elementType.getJavaTypeDescriptor(),
precision,
scale,
length
)
);
}
private static BasicType<?> getArrayElementType(Type arrayType) {
final BasicPluralType<?, ?> containerType = (BasicPluralType<?, ?>) arrayType;
return containerType.getElementType();
}
private static boolean isArray(Type type) {
return type instanceof BasicPluralType<?,?>
&& ((BasicType<?>) type).getJdbcType() instanceof ArrayJdbcType;
}
/**
* Returns {@linkplain org.hibernate.type.SqlTypes SQL type code}
* for this column, or {@code null} if the type code is unknown.
@ -402,28 +375,32 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
public Size getColumnSize(Dialect dialect, Mapping mapping) {
if ( columnSize == null ) {
Type type = getValue().getType();
if ( type instanceof EntityType ) {
type = getTypeForEntityValue( mapping, type, getTypeIndex() );
}
if ( type instanceof ComponentType ) {
type = getTypeForComponentValue( mapping, type, getTypeIndex() );
}
if ( type == null ) {
throw new AssertionFailure( "no typing information available to determine column size" );
}
final JdbcMapping jdbcMapping = (JdbcMapping) type;
columnSize = dialect.getSizeStrategy().resolveSize(
jdbcMapping.getJdbcType(),
jdbcMapping.getJdbcJavaType(),
precision,
scale,
length
);
columnSize = calculateColumnSize( dialect, mapping );
}
return columnSize;
}
Size calculateColumnSize(Dialect dialect, Mapping mapping) {
Type type = getValue().getType();
if ( type instanceof EntityType ) {
type = getTypeForEntityValue( mapping, type, getTypeIndex() );
}
if ( type instanceof ComponentType ) {
type = getTypeForComponentValue( mapping, type, getTypeIndex() );
}
if ( type == null ) {
throw new AssertionFailure( "no typing information available to determine column size" );
}
final JdbcMapping jdbcMapping = (JdbcMapping) type;
return dialect.getSizeStrategy().resolveSize(
jdbcMapping.getJdbcType(),
jdbcMapping.getJdbcJavaType(),
precision,
scale,
length
);
}
private Type getTypeForComponentValue(Mapping mapping, Type type, int typeIndex) {
final Type[] subtypes = ( (ComponentType) type ).getSubtypes();
int typeStartIndex = 0;

View File

@ -174,4 +174,9 @@ public interface Value extends Serializable {
boolean isColumnInsertable(int index);
boolean isColumnUpdateable(int index);
@Incubating
default String getExtraCreateTableInfo() {
return "";
}
}

View File

@ -183,6 +183,10 @@ public class ProcedureParameterImpl<T> extends AbstractQueryParameter<T> impleme
executionContext.getSession()
);
}
@Override
public String toString() {
return "JdbcParameter(" + name + ")";
}
};
}
}

View File

@ -22,7 +22,6 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.SqmVisitableNode;
import org.hibernate.query.sqm.tree.expression.SqmFunction;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -115,7 +114,7 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
for ( int i = 0; i < sqmArguments.size(); i++ ) {
sqlAstArguments.add(
(SqlAstNode) ( (SqmVisitableNode) sqmArguments.get( i ) ).accept( walker )
(SqlAstNode) sqmArguments.get( i ).accept( walker )
);
}
return sqlAstArguments;
@ -129,7 +128,7 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
for ( int i = 0; i < sqmArguments.size(); i++ ) {
typeAccess.argumentIndex = i;
sqlAstArguments.add(
(SqlAstNode) walker.visitWithInferredType( (SqmVisitableNode) sqmArguments.get( i ), typeAccess )
(SqlAstNode) walker.visitWithInferredType( sqmArguments.get( i ), typeAccess )
);
}
return sqlAstArguments;

View File

@ -279,7 +279,6 @@ import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.SqlTreeCreationException;
import org.hibernate.sql.ast.SqlTreeCreationLogger;
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
import org.hibernate.sql.ast.spi.FromClauseAccess;
import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;

View File

@ -204,6 +204,7 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -6117,6 +6118,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
final SqlExpressible expressionType = (SqlExpressible) castTarget.getExpressionType();
if ( expressionType instanceof BasicPluralType<?, ?> ) {
final BasicPluralType<?, ?> containerType = (BasicPluralType<?, ?>) expressionType;
final BasicPluralJavaType<?> javaTypeDescriptor = (BasicPluralJavaType<?>) containerType.getJavaTypeDescriptor();
final BasicType<?> elementType = containerType.getElementType();
final String elementTypeName = sessionFactory.getTypeConfiguration().getDdlTypeRegistry()
.getDescriptor( elementType.getJdbcType().getDdlTypeCode() )
@ -6126,7 +6128,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
castTarget.getPrecision(),
castTarget.getScale()
);
final String arrayTypeName = dialect.getArrayTypeName( elementTypeName );
final String arrayTypeName = dialect.getArrayTypeName(
javaTypeDescriptor.getElementJavaType().getJavaTypeClass().getSimpleName(),
elementTypeName
);
if ( arrayTypeName != null ) {
appendSql( arrayTypeName );
return;

View File

@ -56,6 +56,8 @@ public class StandardTableExporter implements Exporter<Table> {
try {
final String formattedTableName = context.format( tableName );
final StringBuilder extra = new StringBuilder();
final StringBuilder createTable =
new StringBuilder( tableCreateString( table.hasPrimaryKey() ) )
.append( ' ' )
@ -71,6 +73,8 @@ public class StandardTableExporter implements Exporter<Table> {
createTable.append( ", " );
}
appendColumn( createTable, column, table, metadata, dialect, context );
extra.append( column.getValue().getExtraCreateTableInfo() );
}
if ( table.getRowId() != null ) {
String rowIdColumn = dialect.getRowIdColumnString( table.getRowId() );
@ -88,6 +92,8 @@ public class StandardTableExporter implements Exporter<Table> {
createTable.append( ')' );
createTable.append( extra );
if ( table.getComment() != null ) {
createTable.append( dialect.getTableComment( table.getComment() ) );
}

View File

@ -21,6 +21,7 @@ import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.BasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
public abstract class AbstractArrayJavaType<T, E> extends AbstractClassJavaType<T>
@ -53,7 +54,7 @@ public abstract class AbstractArrayJavaType<T, E> extends AbstractClassJavaType<
return ( (ArrayJdbcType) jdbcType ).resolveType(
typeConfiguration,
indicators.getDialect(),
recommendedComponentJdbcType,
new BasicTypeImpl<>( getElementJavaType(), recommendedComponentJdbcType ),
ColumnTypeInformation.EMPTY
);
}

View File

@ -7,7 +7,6 @@
package org.hibernate.type.descriptor.jdbc;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -111,7 +110,7 @@ public class ArrayJdbcType implements JdbcType {
@Override
public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
return new BasicBinder<X>( javaTypeDescriptor, this ) {
return new BasicBinder<>( javaTypeDescriptor, this ) {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
@ -197,7 +196,7 @@ public class ArrayJdbcType implements JdbcType {
@Override
public <X> ValueExtractor<X> getExtractor(final JavaType<X> javaTypeDescriptor) {
return new BasicExtractor<X>( javaTypeDescriptor, this ) {
return new BasicExtractor<>( javaTypeDescriptor, this ) {
@Override
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap( rs.getArray( paramIndex ), options );
@ -230,7 +229,7 @@ public class ArrayJdbcType implements JdbcType {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
if ( !(o instanceof ArrayJdbcType) ) {
return false;
}

View File

@ -12,7 +12,7 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.Incubating;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.query.sqm.CastType;
@ -327,6 +327,15 @@ public interface JdbcType extends Serializable {
}
@Incubating
default void addAuxiliaryDatabaseObjects(JavaType<?> javaType, InFlightMetadataCollector metadataCollector) {
default void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
}
@Incubating
default String getExtraCreateTableInfo(JavaType<?> javaType, String columnName, String tableName, Database database) {
return "";
}
}

View File

@ -13,8 +13,10 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
/**
* Descriptor for a DDL column type. An instance of this type abstracts over
@ -36,7 +38,14 @@ public interface DdlType extends Serializable {
*/
int getSqlTypeCode();
default String getTypeName(Size columnSize, Class<?> returnedClass) {
/**
* Return a type with length, precision, and scale specified by the given
* {@linkplain Size size object}. The given type may be used to
* determine additional aspects of the returned SQL type.
*
* @since 6.3
*/
default String getTypeName(Size columnSize, Type type, DdlTypeRegistry ddlTypeRegistry) {
return getTypeName( columnSize );
}

View File

@ -0,0 +1,50 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.type.descriptor.sql.internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.BasicPluralType;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import static java.sql.Types.ARRAY;
/**
* @author Gavin King
*/
public class ArrayDdlTypeImpl extends DdlTypeImpl {
public ArrayDdlTypeImpl(Dialect dialect) {
super( ARRAY, "array", dialect );
}
@Override
public String getTypeName(Size columnSize, Type type, DdlTypeRegistry ddlTypeRegistry) {
final BasicPluralType<?, ?> pluralType = (BasicPluralType<?, ?>) type;
final BasicPluralJavaType<?> javaTypeDescriptor = (BasicPluralJavaType<?>) pluralType.getJavaTypeDescriptor();
final BasicType<?> elementType = pluralType.getElementType();
final String arrayElementTypeName =
ddlTypeRegistry.getTypeName(
elementType.getJdbcType().getDdlTypeCode(),
dialect.getSizeStrategy().resolveSize(
elementType.getJdbcMapping().getJdbcType(),
elementType.getJavaTypeDescriptor(),
columnSize.getPrecision(),
columnSize.getScale(),
columnSize.getLength()
)
);
return dialect.getArrayTypeName(
javaTypeDescriptor.getElementJavaType().getJavaTypeClass().getSimpleName(),
arrayElementTypeName
);
}
}

View File

@ -25,7 +25,7 @@ public class DdlTypeImpl implements DdlType {
private final String typeNamePattern;
private final String castTypeNamePattern;
private final boolean castTypeNameIsStatic;
private final Dialect dialect;
final Dialect dialect;
public DdlTypeImpl(int sqlTypeCode, String typeNamePattern, Dialect dialect) {
this( sqlTypeCode, typeNamePattern, typeNamePattern, dialect );

View File

@ -8,16 +8,18 @@ package org.hibernate.type.descriptor.sql.internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.DdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import static org.hibernate.type.SqlTypes.ENUM;
import static org.hibernate.type.SqlTypes.NAMED_ENUM;
/**
* A {@link DdlType} representing a native SQL {@code enum} type.
* A {@link DdlType} representing a named native SQL {@code enum} type,
* one that often <em>cannot</em> be treated as a {@code varchar}.
*
* @see org.hibernate.type.SqlTypes#ENUM
* @see org.hibernate.type.SqlTypes#NAMED_ENUM
* @see Dialect#getEnumTypeDeclaration(Class)
*
@ -33,17 +35,16 @@ public class NamedNativeEnumDdlTypeImpl implements DdlType {
@Override
public int getSqlTypeCode() {
// note: also used for NAMED_ENUM
return ENUM;
return NAMED_ENUM;
}
@Override
public String getTypeName(Size columnSize, Class<?> returnedClass) {
return dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) returnedClass );
@Override @SuppressWarnings("unchecked")
public String getTypeName(Size columnSize, Type type, DdlTypeRegistry ddlTypeRegistry) {
return dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) type.getReturnedClass() );
}
@Override
public String getRawTypeName() {
// this
return "enum";
}

View File

@ -8,15 +8,24 @@ package org.hibernate.type.descriptor.sql.internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.DdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import static org.hibernate.type.SqlTypes.ENUM;
/**
* A {@link DdlType} representing a SQL {@code enum} type that
* may be treated as {@code varchar} for most purposes.
*
* @see org.hibernate.type.SqlTypes#ENUM
* @see Dialect#getEnumTypeDeclaration(Class)
*
* @author Gavin King
*/
public class NativeEnumDdlTypeImpl implements DdlType {
private final Dialect dialect;
@ -29,9 +38,9 @@ public class NativeEnumDdlTypeImpl implements DdlType {
return ENUM;
}
@Override
public String getTypeName(Size columnSize, Class<?> returnedClass) {
return dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) returnedClass );
@Override @SuppressWarnings("unchecked")
public String getTypeName(Size columnSize, Type type, DdlTypeRegistry ddlTypeRegistry) {
return dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) type.getReturnedClass() );
}
@Override

View File

@ -148,6 +148,12 @@ public class DdlTypeRegistry implements Serializable {
public String getTypeName(int typeCode, Dialect dialect) {
// explicitly enforce dialect's default precisions
switch ( typeCode ) {
case SqlTypes.CHAR:
case SqlTypes.NCHAR:
case SqlTypes.VARCHAR:
case SqlTypes.NVARCHAR:
case SqlTypes.VARBINARY:
return getTypeName( typeCode, Size.length( Size.DEFAULT_LENGTH ) );
case SqlTypes.DECIMAL:
case SqlTypes.NUMERIC:
return getTypeName( typeCode, Size.precision( dialect.getDefaultDecimalPrecision() ) );
@ -188,6 +194,22 @@ public class DdlTypeRegistry implements Serializable {
return getTypeName( typeCode, size.getLength(), size.getPrecision(), size.getScale() );
}
/**
* Get the SQL type name for the specified {@link java.sql.Types JDBC type code}
* and size, filling in the placemarkers {@code $l}, {@code $p}, and {@code $s}
* with the length, precision, and scale determined by the given {@linkplain Size
* size object}. The returned type name should be of a SQL type large enough to
* accommodate values of the specified size.
*
* @param typeCode the JDBC type code
* @param columnSize an object which determines the length, precision, and scale
* @param type the {@link Type} mapped to the column
*
* @return the associated type name with the smallest capacity that accommodates
* the given size, if available, and the default type name otherwise
*
* @since 6.3
*/
public String getTypeName(int typeCode, Size columnSize, Type type) {
final DdlType descriptor = getDescriptor( typeCode );
if ( descriptor == null ) {
@ -199,7 +221,7 @@ public class DdlTypeRegistry implements Serializable {
)
);
}
return descriptor.getTypeName( columnSize, type.getReturnedClass() );
return descriptor.getTypeName( columnSize, type, this );
}
/**