Replace typeNames in Dialect with SqlType and SqlTypeRegistry that dialects contribute into

This commit is contained in:
Christian Beikov 2022-03-04 20:48:32 +01:00
parent 7a55c7b34b
commit 2c80250b0e
79 changed files with 2179 additions and 1728 deletions

View File

@ -19,7 +19,6 @@ import jakarta.persistence.Id;
import jakarta.persistence.NamedNativeQueries;
import jakarta.persistence.NamedNativeQuery;
import org.hibernate.Session;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
@ -28,8 +27,10 @@ import org.hibernate.annotations.SQLInsert;
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
@ -65,13 +66,14 @@ public class CollectionLoaderTest extends BaseEntityManagerFunctionalTestCase {
@Before
public void init() {
doInJPA(this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap(Session.class);
SessionImplementor session = entityManager.unwrap( SessionImplementor.class);
DdlTypeRegistry ddlTypeRegistry = session.getTypeConfiguration().getDdlTypeRegistry();
session.doWork(connection -> {
try(Statement statement = connection.createStatement();) {
statement.executeUpdate(String.format("ALTER TABLE person %s valid %s",
getDialect().getAddColumnString(), getDialect().getTypeName(Types.BOOLEAN)));
statement.executeUpdate(String.format("ALTER TABLE Person_phones %s valid %s",
getDialect().getAddColumnString(), getDialect().getTypeName(Types.BOOLEAN)));
statement.executeUpdate(String.format( "ALTER TABLE person %s valid %s",
getDialect().getAddColumnString(), ddlTypeRegistry.getTypeName( Types.BOOLEAN, getDialect())));
statement.executeUpdate(String.format( "ALTER TABLE Person_phones %s valid %s",
getDialect().getAddColumnString(), ddlTypeRegistry.getTypeName( Types.BOOLEAN, getDialect())));
}
});
});

View File

@ -8,26 +8,26 @@ package org.hibernate.community.dialect;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.community.dialect.identity.CUBRIDIdentityColumnSupport;
import org.hibernate.community.dialect.sequence.CUBRIDSequenceSupport;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorCUBRIDDatabaseImpl;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SimpleDatabaseVersion;
import org.hibernate.dialect.TimeZoneSupport;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitLimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
@ -37,6 +37,10 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.BinaryFloatDdlType;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
@ -45,6 +49,13 @@ import static org.hibernate.query.sqm.TemporalUnit.MINUTE;
import static org.hibernate.query.sqm.TemporalUnit.NANOSECOND;
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
/**
* An SQL dialect for CUBRID (8.3.x and later).
@ -52,33 +63,55 @@ import static org.hibernate.query.sqm.TemporalUnit.SECOND;
* @author Seok Jeong Il
*/
public class CUBRIDDialect extends Dialect {
private static final DatabaseVersion VERSION = DatabaseVersion.make( 0, 0 );
/**
* Constructs a CUBRIDDialect
*/
public CUBRIDDialect() {
super();
super( SimpleDatabaseVersion.ZERO_VERSION );
}
registerColumnType( Types.BOOLEAN, "bit" );
registerColumnType( Types.TINYINT, "smallint" ); //no 'tinyint'
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return "bit";
case TINYINT:
return "smallint";
//'timestamp' has a very limited range
//'datetime' does not support explicit precision
//(always 3, millisecond precision)
case TIMESTAMP:
return "datetime";
case TIMESTAMP_WITH_TIMEZONE:
return "datetimetz";
}
return super.columnType( sqlTypeCode );
}
//'timestamp' has a very limited range
//'datetime' does not support explicit precision
//(always 3, millisecond precision)
registerColumnType(Types.TIMESTAMP, "datetime" );
registerColumnType(Types.TIMESTAMP, "datetimetz" );
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
//precision of a Mimer 'float(p)' represents
//decimal digits instead of binary digits
ddlTypeRegistry.addDescriptor( new BinaryFloatDdlType( this ) );
//CUBRID has no 'binary' nor 'varbinary', but 'bit' is
//intended to be used for binary data (unfortunately the
//length parameter is measured in bits, not bytes)
registerColumnType( Types.BINARY, "bit($l)" );
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "bit varying($l)" );
registerCubridKeywords();
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( BINARY, "bit($l)", this ) );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARBINARY, columnType( BLOB ), this )
.withTypeCapacity( getMaxVarbinaryLength(), "bit varying($l)" )
.build()
);
}
private void registerCubridKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "TYPE" );
registerKeyword( "YEAR" );
registerKeyword( "MONTH" );
@ -132,11 +165,6 @@ public class CUBRIDDialect extends Dialect {
return 1_073_741_823;
}
@Override
public DatabaseVersion getVersion() {
return VERSION;
}
@Override
public JdbcType resolveSqlTypeDescriptor(
String columnTypeName,
@ -168,13 +196,6 @@ public class CUBRIDDialect extends Dialect {
return 3;
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
//precision of a CUBRID 'float(p)' represents
//decimal digits instead of binary digits
return super.getTypeName( code, binaryToDecimalPrecision( code, size ) );
}
@Override
public int getFloatPrecision() {
return 21; // -> 7 decimal digits
@ -482,4 +503,5 @@ public class CUBRIDDialect extends Dialect {
sqlAppender.append(",timediff(?3,?2))");
sqlAppender.append( diffUnit.conversionFactor( toUnit, this ) );
}
}

View File

@ -8,9 +8,9 @@ package org.hibernate.community.dialect;
import org.hibernate.LockMode;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SimpleDatabaseVersion;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.community.dialect.identity.CacheIdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;
@ -51,6 +51,11 @@ import jakarta.persistence.TemporalType;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
/**
* Dialect for Intersystems Caché SQL 2007.1 and above.
@ -58,26 +63,32 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STR
* @author Jonathan Levinson
*/
public class CacheDialect extends Dialect {
private final DatabaseVersion version = DatabaseVersion.make( 0, 0 );
public CacheDialect() {
super();
// Note: For object <-> SQL datatype mappings see:
// Configuration Manager > Advanced > SQL > System DDL Datatype Mappings
registerColumnType( Types.BOOLEAN, "bit" );
//no explicit precision
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
registerColumnType( Types.BLOB, "image" );
registerColumnType( Types.CLOB, "text" );
super( SimpleDatabaseVersion.ZERO_VERSION );
}
public CacheDialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
super( info );
}
@Override
protected String columnType(int sqlTypeCode) {
// Note: For object <-> SQL datatype mappings see:
// Configuration Manager > Advanced > SQL > System DDL Datatype Mappings
switch ( sqlTypeCode ) {
case BOOLEAN:
return "bit";
//no explicit precision
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
case BLOB:
return "image";
case CLOB:
return "text";
}
return super.columnType( sqlTypeCode );
}
@Override
@ -99,11 +110,6 @@ public class CacheDialect extends Dialect {
);
}
@Override
public DatabaseVersion getVersion() {
return version;
}
@Override
public JdbcType resolveSqlTypeDescriptor(
String columnTypeName,

View File

@ -17,8 +17,8 @@ import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.community.dialect.identity.FirebirdIdentityColumnSupport;
import org.hibernate.community.dialect.pagination.SkipFirstLimitHandler;
import org.hibernate.community.dialect.sequence.FirebirdSequenceSupport;
@ -33,7 +33,6 @@ import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
@ -58,6 +57,7 @@ import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
@ -71,11 +71,23 @@ import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.BinaryFloatDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TIME_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_END;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_DATE;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIME;
@ -93,8 +105,6 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithM
*/
public class FirebirdDialect extends Dialect {
private final DatabaseVersion version;
@SuppressWarnings("unused")
public FirebirdDialect() {
this( DatabaseVersion.make( 2, 5 ) );
@ -114,15 +124,47 @@ public class FirebirdDialect extends Dialect {
// cast (not even when wrapped in a function call)
public FirebirdDialect(DatabaseVersion version) {
super();
this.version = version;
super( version );
}
if ( version.isBefore( 3, 0 ) ) {
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
//'boolean' type introduced in 3.0
registerColumnType( Types.BOOLEAN, "smallint" );
case BOOLEAN:
return getVersion().isBefore( 3, 0 ) ? "smallint" : super.columnType( sqlTypeCode );
case TINYINT:
return "smallint";
//no precision for 'timestamp' type
case TIMESTAMP:
return "timestamp";
case TIME_WITH_TIMEZONE:
return getVersion().isBefore( 4, 0 ) ? "time" : super.columnType( sqlTypeCode );
case TIMESTAMP_WITH_TIMEZONE:
return getVersion().isBefore( 4, 0 ) ? "timestamp" : "timestamp with time zone";
case BINARY:
return getVersion().isBefore( 4, 0 ) ? "char($l) character set octets" : super.columnType( sqlTypeCode );
case VARBINARY:
return getVersion().isBefore( 4, 0 ) ? "varchar($l) character set octets" : super.columnType( sqlTypeCode );
case BLOB:
return "blob sub_type binary";
case CLOB:
case NCLOB:
return "blob sub_type text";
}
return super.columnType( sqlTypeCode );
}
registerColumnType( Types.TINYINT, "smallint" );
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getVersion().isBefore( 4, 0 ) ) {
//precision of a Firebird 3 and earlier 'float(p)' represents
//decimal digits instead of binary digits
ddlTypeRegistry.addDescriptor( new BinaryFloatDdlType( this ) );
}
// Note: according to the documentation, Firebird has
// just two floating point types:
@ -131,29 +173,6 @@ public class FirebirdDialect extends Dialect {
// However, it turns out that Firebird actually supports
// the ANSI types 'real', 'float(p)', 'double precision'.
// So we don't override anything here.
//no precision for 'timestamp' type
registerColumnType( Types.TIMESTAMP, "timestamp" );
if ( getVersion().isBefore( 4, 0 ) ) {
// No time zone support, map to without time zone types
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
registerColumnType( Types.TIME_WITH_TIMEZONE, "time" );
}
else {
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp with time zone" );
}
registerColumnType( Types.VARCHAR, "blob sub_type text" );
if ( getVersion().isBefore( 4, 0 ) ) {
registerColumnType( Types.BINARY, "char($l) character set octets" );
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "varchar($l) character set octets" );
}
registerColumnType( Types.VARBINARY, "blob sub_type binary" );
registerColumnType( Types.BLOB, "blob sub_type binary" );
registerColumnType( Types.CLOB, "blob sub_type text" );
registerColumnType( Types.NCLOB, "blob sub_type text" ); // Firebird doesn't have NCLOB, but Jaybird emulates NCLOB support
}
@Override
@ -168,11 +187,6 @@ public class FirebirdDialect extends Dialect {
return 32_756;
}
@Override
public DatabaseVersion getVersion() {
return version;
}
@Override
public int getDefaultStatementBatchSize() {
return 0;
@ -209,19 +223,6 @@ public class FirebirdDialect extends Dialect {
: super.getPreferredSqlTypeCodeForBoolean();
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
if ( getVersion().isBefore( 4, 0 ) ) {
//precision of a Firebird 3 and earlier 'float(p)' represents
//decimal digits instead of binary digits
return super.getTypeName( code, binaryToDecimalPrecision( code, size ) );
}
else {
// Firebird 4 and higher supports standard 'float(p)' (with precision in binary digits)
return super.getTypeName( code, size );
}
}
@Override
public int getFloatPrecision() {
return getVersion().isBefore( 4, 0 )
@ -514,7 +515,7 @@ public class FirebirdDialect extends Dialect {
// Additional reserved words
// The Hibernate list of SQL:2003 reserved words doesn't contain all SQL:2003 reserved words,
// and Firebird is finicky when it comes to reserved words
if ( version.isSameOrAfter( 3, 0 ) ) {
if ( getVersion().isSameOrAfter( 3, 0 ) ) {
builder.applyReservedWords(
"AVG", "BOOLEAN", "CHARACTER_LENGTH", "CHAR_LENGTH", "CORR", "COUNT",
"COVAR_POP", "COVAR_SAMP", "EXTRACT", "LOWER", "MAX", "MIN", "OCTET_LENGTH", "POSITION",

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.community.dialect;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.Replacer;
@ -45,6 +46,7 @@ import org.hibernate.query.sqm.sql.SqmTranslator;
import org.hibernate.query.sqm.sql.SqmTranslatorFactory;
import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
@ -55,10 +57,26 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorInformixDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import java.sql.Types;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.FLOAT;
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.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARBINARY;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.TIME;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.SqlTypes.VARCHAR;
/**
* Dialect for Informix 7.31.UD3 with Informix
@ -68,7 +86,6 @@ import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtract
*/
public class InformixDialect extends Dialect {
private final DatabaseVersion version;
private final UniqueDelegate uniqueDelegate;
private final LimitHandler limitHandler;
@ -86,28 +103,7 @@ public class InformixDialect extends Dialect {
* Informix type mappings.
*/
public InformixDialect(DatabaseVersion version) {
super();
this.version = version;
registerColumnType( Types.TINYINT, "smallint" );
registerColumnType( Types.BIGINT, "int8" );
//Ingres ignores the precision argument in
//float(n) and just always defaults to
//double precision.
//TODO: return 'smallfloat' when n <= 24
registerColumnType( Types.TIME, "datetime hour to second" );
registerColumnType( Types.TIMESTAMP, "datetime year to fraction($p)" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "datetime year to fraction($p)" );
//these types have no defined length
registerColumnType( Types.BINARY, "byte" );
registerColumnType( Types.VARBINARY, "byte" );
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "lvarchar($l)" );
registerColumnType( Types.VARCHAR, "text" );
super(version);
uniqueDelegate = new InformixUniqueDelegate( this );
@ -119,6 +115,64 @@ public class InformixDialect extends Dialect {
: new SkipFirstLimitHandler( getVersion().isSameOrAfter( 11 ) );
}
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case TINYINT:
return "smallint";
case BIGINT:
return "int8";
case TIME:
return "datetime hour to second";
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "datetime year to fraction($p)";
//these types have no defined length
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
return "byte";
case LONGVARCHAR:
case LONGNVARCHAR:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "text";
case VARCHAR:
case NVARCHAR:
return "lvarchar($l)";
}
return super.columnType( sqlTypeCode );
}
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
//Ingres ignores the precision argument in
//float(n) and just always defaults to
//double precision.
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( FLOAT, "float($p)", this )
.withTypeCapacity( 24, "smallfloat" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( LONGVARCHAR ), this )
.withTypeCapacity( 255, "varchar($l)" )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NVARCHAR, columnType( LONGNVARCHAR ), this )
.withTypeCapacity( 255, "varchar($l)" )
.withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) )
.build()
);
}
@Override
public int getMaxVarbinaryLength() {
//there's no varbinary type, only byte
@ -131,11 +185,6 @@ public class InformixDialect extends Dialect {
return 32_739;
}
@Override
public DatabaseVersion getVersion() {
return version;
}
@Override
public int getDefaultDecimalPrecision() {
//the maximum

View File

@ -12,6 +12,7 @@ import org.hibernate.community.dialect.identity.Ingres10IdentityColumnSupport;
import org.hibernate.community.dialect.identity.Ingres9IdentityColumnSupport;
import org.hibernate.community.dialect.pagination.FirstLimitHandler;
import org.hibernate.community.dialect.pagination.IngresLimitHandler;
import org.hibernate.community.dialect.sequence.IngresLegacySequenceSupport;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
@ -63,6 +64,21 @@ import jakarta.persistence.TemporalType;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.DATE;
import static org.hibernate.type.SqlTypes.DECIMAL;
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.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARBINARY;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.NUMERIC;
import static org.hibernate.type.SqlTypes.VARBINARY;
/**
* An SQL dialect for Ingres 9.2.
@ -91,83 +107,74 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STR
public class IngresDialect extends Dialect {
private final LimitHandler limitHandler;
private final DatabaseVersion version;
private final SequenceSupport sequenceSupport;
public IngresDialect() {
this( DatabaseVersion.make( 9, 2 ) );
}
public IngresDialect(DialectResolutionInfo info) {
this( info.makeCopy() );
registerKeywords( info );
}
public IngresDialect() {
this( DatabaseVersion.make( 9, 2 ) );
}
/**
* Constructs a IngresDialect
*/
public IngresDialect(DatabaseVersion version) {
super();
this.version = version;
if ( version.isBefore( 10 ) ) {
registerColumnType( Types.BOOLEAN, "tinyint" );
super( version );
if ( getVersion().isSameOrAfter( 9, 3 ) ) {
limitHandler = IngresLimitHandler.INSTANCE;
sequenceSupport = ANSISequenceSupport.INSTANCE;
}
else {
registerColumnType( Types.BOOLEAN, "boolean" );
limitHandler = FirstLimitHandler.INSTANCE;
sequenceSupport = IngresLegacySequenceSupport.INSTANCE;
}
}
registerColumnType( Types.NUMERIC, "decimal($p, $s)" ); //Ingres has no 'numeric' type
registerColumnType( Types.BINARY, "byte($l)" );
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "varbyte($l)" );
//note: 'long byte' is a synonym for 'blob'
registerColumnType( Types.VARBINARY, "long byte($l)" );
@Override
protected String columnType(int sqlTypeCode) {
//TODO: should we be using nchar/nvarchar/long nvarchar
// here? I think Ingres char/varchar types don't
// support Unicode. Copy what AbstractHANADialect
// does with a Hibernate property to config this.
registerColumnType( Types.CHAR, "char($l)" );
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "varchar($l)" );
//note: 'long varchar' is a synonym for 'clob'
registerColumnType( Types.VARCHAR, "long varchar($l)" );
registerColumnType( Types.NCHAR, "nchar($l)" );
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "nvarchar($l)" );
//note: 'long nvarchar' is a synonym for 'nclob'
registerColumnType( Types.NVARCHAR, "long nvarchar($l)" );
if ( getVersion().isSameOrAfter( 9, 3 ) ) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return getVersion().isBefore( 10 ) ? "tinyint" : super.columnType( sqlTypeCode );
// Not completely necessary, given that Ingres
// can be configured to set DATE = ANSIDATE
registerColumnType( Types.DATE, "ansidate" );
case DATE:
return getVersion().isBefore( 10 ) && getVersion().isSameOrAfter( 9, 3 )
? "ansidate"
: super.columnType( sqlTypeCode );
//Ingres has no 'numeric' type
case NUMERIC:
return castType( DECIMAL );
case BINARY:
return "byte($l)";
case VARBINARY:
return "varbyte($l)";
//note: 'long byte' is a synonym for 'blob'
case LONGVARBINARY:
case LONG32VARBINARY:
case BLOB:
return "long byte($l)";
//note: 'long varchar' is a synonym for 'clob'
case LONGVARCHAR:
case LONG32VARCHAR:
case CLOB:
return "long varchar($l)";
//note: 'long varchar' is a synonym for 'nclob'
case LONGNVARCHAR:
case LONG32NVARCHAR:
case NCLOB:
return "long nvarchar($l)";
}
limitHandler = getVersion().isBefore( 9, 3 ) ? FirstLimitHandler.INSTANCE : IngresLimitHandler.INSTANCE;
sequenceSupport = new ANSISequenceSupport() {
@Override
public boolean supportsPooledSequences() {
return getVersion().isSameOrAfter( 9, 3 );
}
};
return super.columnType( sqlTypeCode );
}
// @Override
// protected void initDefaultProperties() {
// super.initDefaultProperties();
//
// if ( getVersion().isBefore( 10 ) ) {
// // There is no support for a native boolean type that accepts values
// // of true, false or unknown. Using the tinyint type requires
// // substitutions of true and false.
// getDefaultProperties().setProperty( Environment.QUERY_SUBSTITUTIONS, "true=1,false=0" );
// }
// }
@Override
public boolean getDefaultUseGetGeneratedKeys() {
// Ingres driver supports getGeneratedKeys but only in the following
@ -183,11 +190,6 @@ public class IngresDialect extends Dialect {
return false;
}
@Override
public DatabaseVersion getVersion() {
return version;
}
@Override
public int getMaxVarcharLength() {
// the maximum possible (configurable) value for

View File

@ -13,7 +13,6 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.community.dialect.sequence.MaxDBSequenceSupport;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorSAPDBDatabaseImpl;
import org.hibernate.dialect.AbstractTransactSQLDialect;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.pagination.LimitHandler;
@ -40,6 +39,15 @@ import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.NUMERIC;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
/**
* A SQL dialect compatible with SAP MaxDB.
@ -49,22 +57,34 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STR
public class MaxDBDialect extends Dialect {
public MaxDBDialect() {
super();
registerColumnType( Types.TINYINT, "smallint" );
super( ZERO_VERSION );
}
registerColumnType( Types.BIGINT, "fixed(19,0)" );
public MaxDBDialect(DialectResolutionInfo info) {
super( info );
}
registerColumnType( Types.NUMERIC, "fixed($p,$s)" );
registerColumnType( Types.DECIMAL, "fixed($p,$s)" );
//no explicit precision
registerColumnType(Types.TIMESTAMP, "timestamp");
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamp");
registerColumnType( Types.VARBINARY, "long byte" );
registerColumnType( Types.CLOB, "long varchar" );
registerColumnType( Types.BLOB, "long byte" );
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case TINYINT:
return "smallint";
case BIGINT:
return "fixed(19,0)";
case NUMERIC:
case DECIMAL:
return "fixed($p,$s)";
//no explicit precision
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
case VARBINARY:
case BLOB:
return "long byte";
case CLOB:
return "long varchar";
}
return super.columnType( sqlTypeCode );
}
@Override
@ -96,16 +116,6 @@ public class MaxDBDialect extends Dialect {
);
}
public MaxDBDialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
}
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
@Override
public int getDefaultStatementBatchSize() {
return 15;

View File

@ -6,10 +6,8 @@
*/
package org.hibernate.community.dialect;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.community.dialect.identity.MimerSQLIdentityColumnSupport;
import org.hibernate.community.dialect.sequence.MimerSequenceSupport;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorMimerSQLDatabaseImpl;
@ -20,13 +18,13 @@ import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
@ -34,10 +32,26 @@ 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.SequenceInformationExtractor;
import org.hibernate.type.descriptor.sql.internal.BinaryFloatDdlType;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
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.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARCHAR;
/**
* A dialect for Mimer SQL 11.
@ -57,38 +71,56 @@ public class MimerSQLDialect extends Dialect {
// in a cast or function call
public MimerSQLDialect() {
super();
//no 'tinyint', so use integer with 3 decimal digits
registerColumnType( Types.TINYINT, "integer(3)" );
//Mimer CHARs are ASCII!!
registerColumnType( Types.CHAR, "nchar($l)" );
registerColumnType( Types.VARCHAR, 5_000, "nvarchar($l)" );
registerColumnType( Types.VARCHAR, "nclob($l)" );
registerColumnType( Types.NVARCHAR, 5_000, "nvarchar($l)" );
registerColumnType( Types.NVARCHAR, "nclob($l)" );
registerColumnType( Types.VARBINARY, 15_000, "varbinary($l)" );
registerColumnType( Types.VARBINARY, "blob($l)" );
//default length is 1M, which is quite low
registerColumnType( Types.BLOB, "blob($l)" );
registerColumnType( Types.CLOB, "nclob($l)" );
registerColumnType( Types.NCLOB, "nclob($l)" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp($p)" );
super( DatabaseVersion.make( 11 ) );
}
public MimerSQLDialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
super( info );
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
//no 'tinyint', so use integer with 3 decimal digits
case TINYINT:
return "integer(3)";
case TIMESTAMP_WITH_TIMEZONE:
return columnType( TIMESTAMP );
//Mimer CHARs are ASCII!!
case CHAR:
return columnType( NCHAR );
case VARCHAR:
return columnType( NVARCHAR );
case LONGVARCHAR:
return columnType( LONGNVARCHAR );
case LONG32VARCHAR:
return columnType( LONG32NVARCHAR );
case CLOB:
return columnType( NCLOB );
}
return super.columnType( sqlTypeCode );
}
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
//precision of a Mimer 'float(p)' represents
//decimal digits instead of binary digits
return super.getTypeName( code, binaryToDecimalPrecision( code, size ) );
ddlTypeRegistry.addDescriptor( new BinaryFloatDdlType( this ) );
//Mimer CHARs are ASCII!!
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( LONGVARCHAR ), "nvarchar(" + getMaxNVarcharLength() + ")", this )
.withTypeCapacity( getMaxNVarcharLength(), columnType( VARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( LONGVARCHAR, columnType( LONGVARCHAR ), "nvarchar(" + getMaxNVarcharLength() + ")", this )
.withTypeCapacity( getMaxNVarcharLength(), columnType( VARCHAR ) )
.build()
);
}
// @Override

View File

@ -14,6 +14,7 @@ import org.hibernate.dialect.AbstractTransactSQLDialect;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SimpleDatabaseVersion;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy;
@ -48,6 +49,26 @@ import org.jboss.logging.Logger;
import jakarta.persistence.TemporalType;
import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
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.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARBINARY;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.SqlTypes.VARCHAR;
/**
* This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS).
@ -71,10 +92,17 @@ public class RDMSOS2200Dialect extends Dialect {
* Constructs a RDMSOS2200Dialect
*/
public RDMSOS2200Dialect() {
super();
super( SimpleDatabaseVersion.ZERO_VERSION );
// Display the dialect version.
LOG.rdmsOs2200Dialect();
}
public RDMSOS2200Dialect(DialectResolutionInfo info) {
super( info );
}
@Override
protected String columnType(int sqlTypeCode) {
/*
* For a list of column types to register, see section A-1
* in 7862 7395, the Unisys JDBC manual.
@ -100,28 +128,39 @@ public class RDMSOS2200Dialect extends Dialect {
* Note that $l (dollar-L) will use the length value if provided.
* Also new for Hibernate3 is the $p percision and $s (scale) parameters
*/
registerColumnType( Types.BOOLEAN, "smallint" );
registerColumnType( Types.TINYINT, "smallint" );
registerColumnType( Types.BIGINT, "numeric(19,0)" );
registerColumnType( Types.BLOB, "blob($l)" );
//no 'binary' nor 'varbinary' so use 'blob'
registerColumnType( Types.BINARY, "blob($l)" );
registerColumnType( Types.VARBINARY, "blob($l)" );
//'varchar' is not supported in RDMS for OS 2200
//(but it is for other flavors of RDMS)
//'character' means ASCII by default, 'unicode(n)'
//means 'character(n) character set "UCS-2"'
registerColumnType( Types.CHAR, "unicode($l)" );
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "unicode($l)" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp($p)" );
}
public RDMSOS2200Dialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
switch ( sqlTypeCode ) {
case BOOLEAN:
case TINYINT:
return "smallint";
case BIGINT:
return "numeric(19,0)";
//'varchar' is not supported in RDMS for OS 2200
//(but it is for other flavors of RDMS)
//'character' means ASCII by default, 'unicode(n)'
//means 'character(n) character set "UCS-2"'
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONG32VARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
return "unicode($l)";
case CLOB:
case NCLOB:
return "clob($l)";
//no 'binary' nor 'varbinary' so use 'blob'
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
case BLOB:
return "blob($l)";
case TIMESTAMP_WITH_TIMEZONE:
return columnType( TIMESTAMP );
}
return super.columnType( sqlTypeCode );
}
@Override

View File

@ -53,11 +53,10 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import jakarta.persistence.TemporalType;
@ -72,14 +71,15 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INT
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.NUMERIC;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.FLOAT;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.VARCHAR;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TIME_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
@ -95,7 +95,6 @@ public class SQLiteDialect extends Dialect {
private static final SQLiteIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new SQLiteIdentityColumnSupport();
private final UniqueDelegate uniqueDelegate;
private final DatabaseVersion version;
public SQLiteDialect(DialectResolutionInfo info) {
this( info.makeCopy() );
@ -107,39 +106,32 @@ public class SQLiteDialect extends Dialect {
}
public SQLiteDialect(DatabaseVersion version) {
super();
this.version = version;
if ( version.isBefore( 3 ) ) {
registerColumnType( Types.DECIMAL, "numeric($p,$s)" );
registerColumnType( Types.CHAR, "char" );
registerColumnType( Types.NCHAR, "nchar" );
}
// No precision support
registerColumnType( Types.FLOAT, "float" );
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
registerColumnType( Types.TIME_WITH_TIMEZONE, "time" );
registerColumnType( Types.BINARY, "blob" );
registerColumnType( Types.VARBINARY, "blob" );
super( version );
uniqueDelegate = new SQLiteUniqueDelegate( this );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case DECIMAL:
return getVersion().isBefore( 3 ) ? columnType( SqlTypes.NUMERIC ) : super.columnType( sqlTypeCode );
case CHAR:
return getVersion().isBefore( 3 ) ? "char" : super.columnType( sqlTypeCode );
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "text";
return getVersion().isBefore( 3 ) ? "nchar" : super.columnType( sqlTypeCode );
// No precision support
case FLOAT:
return "float";
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
case TIME_WITH_TIMEZONE:
return "time";
case BINARY:
case VARBINARY:
return "blob";
}
return super.getUnboundedTypeName( jdbcType, javaType );
return super.columnType( sqlTypeCode );
}
@Override
@ -163,11 +155,6 @@ public class SQLiteDialect extends Dialect {
return uniqueDelegate;
}
@Override
public DatabaseVersion getVersion() {
return version;
}
/**
* The {@code extract()} function returns {@link TemporalUnit#DAY_OF_WEEK}
* numbered from 0 to 6. This isn't consistent with what most other

View File

@ -50,31 +50,22 @@ public class SybaseAnywhereDialect extends SybaseDialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
case DATE:
return "date";
case TIME:
return "time";
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case TIMESTAMP:
return "timestamp";
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp with time zone";
//these types hold up to 2 GB
case LONG32VARCHAR:
return "long varchar";
case LONG32NVARCHAR:
return "long nvarchar";
case LONG32VARBINARY:
return "long binary";
case NCLOB:
return "ntext";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override

View File

@ -50,6 +50,7 @@ import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement;
import java.sql.ResultSet;
@ -61,6 +62,11 @@ import java.util.Map;
import jakarta.persistence.TemporalType;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
/**
* A dialect for the Teradata database created by MCR as part of the
@ -70,8 +76,6 @@ import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtract
*/
public class TeradataDialect extends Dialect {
private final DatabaseVersion version;
private static final int PARAM_LIST_SIZE_LIMIT = 1024;
public TeradataDialect(DialectResolutionInfo info) {
@ -84,24 +88,12 @@ public class TeradataDialect extends Dialect {
}
public TeradataDialect(DatabaseVersion version) {
super();
this.version = version;
registerColumnType( Types.BOOLEAN, "byteint" );
registerColumnType( Types.TINYINT, "byteint" );
registerColumnType( Types.BINARY, "byte($l)" );
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "varbyte($l)" );
if ( getVersion().isBefore( 13 ) ) {
registerColumnType( Types.BIGINT, "numeric(19,0)" );
}
else {
//'bigint' has been there since at least version 13
registerColumnType( Types.BIGINT, "bigint" );
}
super( version );
}
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "password" );
registerKeyword( "type" );
registerKeyword( "title" );
@ -116,6 +108,23 @@ public class TeradataDialect extends Dialect {
registerKeyword( "class" );
}
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
case TINYINT:
return "byteint";
//'bigint' has been there since at least version 13
case BIGINT:
return getVersion().isBefore( 13 ) ? "numeric(19,0)" : "bigint";
case BINARY:
return "byte($l)";
case VARBINARY:
return "varbyte($l)";
}
return super.columnType( sqlTypeCode );
}
@Override
public int getDefaultStatementBatchSize() {
return getVersion().isBefore( 14 )
@ -173,11 +182,6 @@ public class TeradataDialect extends Dialect {
};
}
@Override
public DatabaseVersion getVersion() {
return version;
}
@Override
public int getPreferredSqlTypeCodeForBoolean() {
return Types.BIT;
@ -389,7 +393,7 @@ public class TeradataDialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
String v = "null";
switch ( sqlType ) {

View File

@ -8,7 +8,6 @@ package org.hibernate.community.dialect;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.RowLockStrategy;
import org.hibernate.dialect.function.CommonFunctionFactory;
@ -38,9 +37,11 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorTimesTenDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.Types;
import jakarta.persistence.TemporalType;
@ -67,45 +68,44 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STR
public class TimesTenDialect extends Dialect {
public TimesTenDialect() {
super();
//Note: these are the correct type mappings
// for the default Oracle type mode
// TypeMode=0
registerColumnType( Types.BOOLEAN, "tt_tinyint" );
registerColumnType( Types.TINYINT, "tt_tinyint" );
registerColumnType( Types.SMALLINT, "tt_smallint" );
registerColumnType( Types.INTEGER, "tt_integer" );
registerColumnType( Types.BIGINT, "tt_bigint" );
//note that 'binary_float'/'binary_double' might
//be better mappings for Java Float/Double
//'numeric'/'decimal' are synonyms for 'number'
registerColumnType( Types.NUMERIC, "number($p,$s)" );
registerColumnType( Types.DECIMAL, "number($p,$s)" );
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "varchar2($l)" );
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "nvarchar2($l)" );
//do not use 'date' because it's a datetime
registerColumnType( Types.DATE, "tt_date" );
//'time' and 'tt_time' are synonyms
registerColumnType( Types.TIME, "tt_time" );
//`timestamp` has more precision than `tt_timestamp`
// registerColumnType(Types.TIMESTAMP, "tt_timestamp");
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp($p)" );
super( ZERO_VERSION );
}
public TimesTenDialect(DialectResolutionInfo info) {
this();
registerKeywords( info );
super( info );
}
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
//Note: these are the correct type mappings
// for the default Oracle type mode
// TypeMode=0
case SqlTypes.BOOLEAN:
case SqlTypes.TINYINT:
return "tt_tinyint";
case SqlTypes.SMALLINT:
return "tt_smallint";
case SqlTypes.INTEGER:
return "tt_integer";
case SqlTypes.BIGINT:
return "tt_bigint";
//note that 'binary_float'/'binary_double' might
//be better mappings for Java Float/Double
//'numeric'/'decimal' are synonyms for 'number'
case SqlTypes.NUMERIC:
case SqlTypes.DECIMAL:
return "number($p,$s)";
case SqlTypes.DATE:
return "tt_date";
case SqlTypes.TIME:
return "tt_time";
//`timestamp` has more precision than `tt_timestamp`
case SqlTypes.TIMESTAMP_WITH_TIMEZONE:
return "timestamp($p)";
}
return super.columnType( sqlTypeCode );
}
@Override
@ -399,7 +399,7 @@ public class TimesTenDialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
switch (sqlType) {
case Types.VARCHAR:
case Types.CHAR:

View File

@ -0,0 +1,23 @@
/*
* 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.community.dialect.sequence;
import org.hibernate.dialect.sequence.ANSISequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
/**
* Sequence support for {@link org.hibernate.community.dialect.IngresDialect}.
*/
public final class IngresLegacySequenceSupport extends ANSISequenceSupport {
public static final SequenceSupport INSTANCE = new IngresLegacySequenceSupport();
@Override
public boolean supportsPooledSequences() {
return false;
}
}

View File

@ -296,24 +296,6 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys, getTypeConfiguration() ) );
}
@Override
public void contributeJavaType(JavaType<?> descriptor) {
this.bootstrapContext.getTypeConfiguration().getJavaTypeRegistry().addDescriptor( descriptor );
}
@Override
public void contributeJdbcType(JdbcType descriptor) {
this.bootstrapContext.getTypeConfiguration().getJdbcTypeRegistry().addDescriptor( descriptor );
}
@Override
public <T> void contributeType(UserType<T> descriptor) {
bootstrapContext.getTypeConfiguration().getBasicTypeRegistry().register(
descriptor,
descriptor.returnedClass().getName()
);
}
@Override
public TypeConfiguration getTypeConfiguration() {
return bootstrapContext.getTypeConfiguration();

View File

@ -7,6 +7,7 @@
package org.hibernate.boot.model;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.StandardBasicTypeTemplate;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
@ -27,25 +28,35 @@ public interface TypeContributions {
* Add the JavaType to the {@link TypeConfiguration}'s
* {@link JavaTypeRegistry}
*/
void contributeJavaType(JavaType<?> descriptor);
default void contributeJavaType(JavaType<?> descriptor) {
getTypeConfiguration().getJavaTypeRegistry().addDescriptor( descriptor );
}
/**
* Add the JdbcType to the {@link TypeConfiguration}'s
* {@link JdbcTypeRegistry}
*/
void contributeJdbcType(JdbcType descriptor);
default void contributeJdbcType(JdbcType descriptor) {
getTypeConfiguration().getJdbcTypeRegistry().addDescriptor( descriptor );
}
/**
* Registers a UserType as the implicit (auto-applied) type
* for values of type {@link UserType#returnedClass()}
*/
<T> void contributeType(UserType<T> type);
default <T> void contributeType(UserType<T> type) {
contributeType( type, type.returnedClass().getName() );
}
/**
* @deprecated See user-guide section `2.2.46. TypeContributor` for details - `basic_types.adoc`
*/
@Deprecated(since = "6.0")
void contributeType(BasicType<?> type);
default void contributeType(BasicType<?> type) {
getTypeConfiguration().getBasicTypeRegistry().register( type );
final JavaType<?> javaType = type.getJavaTypeDescriptor();
getTypeConfiguration().getJavaTypeRegistry().resolveDescriptor( javaType.getJavaType(), () -> javaType );
}
/**
* @deprecated Use {@link #contributeType(BasicType)} instead. Basic
@ -58,7 +69,11 @@ public interface TypeContributions {
* registration keys and call {@link #contributeType(BasicType)} instead
*/
@Deprecated(since = "5.3")
void contributeType(BasicType<?> type, String... keys);
default void contributeType(BasicType<?> type, String... keys) {
getTypeConfiguration().getBasicTypeRegistry().register( type, keys );
final JavaType<?> javaType = type.getJavaTypeDescriptor();
getTypeConfiguration().getJavaTypeRegistry().resolveDescriptor( javaType.getJavaType(), () -> javaType );
}
/**
* @deprecated Use {@link #contributeType(BasicType)} instead.
@ -71,5 +86,9 @@ public interface TypeContributions {
* and call {@link #contributeType(BasicType)} instead
*/
@Deprecated(since = "5.3")
void contributeType(UserType<?> type, String... keys);
default void contributeType(UserType<?> type, String... keys) {
final CustomType<?> customType = getTypeConfiguration().getBasicTypeRegistry().register( type, keys );
final JavaType<?> javaType = customType.getJavaTypeDescriptor();
getTypeConfiguration().getJavaTypeRegistry().resolveDescriptor( javaType.getJavaType(), () -> javaType );
}
}

View File

@ -44,15 +44,12 @@ import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.CustomType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.internal.NamedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserType;
import org.jboss.jandex.IndexView;
import org.jboss.logging.Logger;
@ -363,57 +360,7 @@ public class MetadataBuildingProcess {
final ClassLoaderService classLoaderService = options.getServiceRegistry().getService( ClassLoaderService.class );
final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final TypeContributions typeContributions = new TypeContributions() {
@Override
public void contributeType(BasicType type) {
getBasicTypeRegistry().register( type );
conditionallyRegisterJtd( type.getJavaTypeDescriptor() );
}
private void conditionallyRegisterJtd(JavaType jtd) {
final JavaTypeRegistry jtdRegistry = getTypeConfiguration().getJavaTypeRegistry();
jtdRegistry.resolveDescriptor( jtd.getJavaTypeClass(), () -> jtd );
}
@Override
public void contributeType(BasicType type, String... keys) {
getBasicTypeRegistry().register( type, keys );
conditionallyRegisterJtd( type.getJavaTypeDescriptor() );
}
@Override
public void contributeType(UserType type, String[] keys) {
contributeType( new CustomType<Object>( type, keys, getTypeConfiguration() ) );
}
@Override
public void contributeJavaType(JavaType<?> descriptor) {
typeConfiguration.getJavaTypeRegistry().addDescriptor( descriptor );
}
@Override
public void contributeJdbcType(JdbcType descriptor) {
typeConfiguration.getJdbcTypeRegistry().addDescriptor( descriptor );
}
@Override
public <T> void contributeType(UserType<T> descriptor) {
typeConfiguration.getBasicTypeRegistry().register(
descriptor,
descriptor.returnedClass().getName()
);
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
final BasicTypeRegistry getBasicTypeRegistry() {
return getTypeConfiguration().getBasicTypeRegistry();
}
};
final TypeContributions typeContributions = () -> typeConfiguration;
// add Dialect contributed types
final Dialect dialect = options.getServiceRegistry().getService( JdbcServices.class ).getDialect();

View File

@ -55,7 +55,6 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHA
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.tool.schema.internal.StandardTableExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
@ -65,6 +64,9 @@ import org.hibernate.type.descriptor.java.DoubleJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.*;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.internal.BasicTypeImpl;
import java.io.*;
@ -81,6 +83,27 @@ import jakarta.persistence.TemporalType;
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.DOUBLE;
import static org.hibernate.type.SqlTypes.GEOMETRY;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.LONGNVARCHAR;
import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.NUMERIC;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.POINT;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARCHAR;
/**
* An abstract base class for SAP HANA dialects.
* <p>
@ -165,57 +188,77 @@ public abstract class AbstractHANADialect extends Dialect {
};
public AbstractHANADialect(DatabaseVersion version) {
super(version);
super( version );
this.useUnicodeStringTypes = useUnicodeStringTypesDefault();
this.clobTypeDescriptor = new HANAClobJdbcType(
MAX_LOB_PREFETCH_SIZE_DEFAULT_VALUE,
useUnicodeStringTypesDefault()
);
}
// Note that 38 is the maximum precision HANA supports
registerColumnType( Types.DECIMAL, "decimal($p, $s)" );
//there is no 'numeric' type in HANA
registerColumnType( Types.NUMERIC, "decimal($p, $s)" );
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return useLegacyBooleanType ? "tinyint" : super.columnType( sqlTypeCode );
case NUMERIC:
//there is no 'numeric' type in HANA
return columnType( DECIMAL );
//'double precision' syntax not supported
case DOUBLE:
return "double";
//no explicit precision
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
//there is no 'char' or 'nchar' type in HANA
case CHAR:
case VARCHAR:
return isUseUnicodeStringTypes() ? columnType( NVARCHAR ) : super.columnType( VARCHAR );
case NCHAR:
return columnType( NVARCHAR );
case LONG32VARCHAR:
return isUseUnicodeStringTypes() ? columnType( LONG32NVARCHAR ) : super.columnType( LONG32VARCHAR );
case LONGVARCHAR:
return isUseUnicodeStringTypes() ? columnType( LONGNVARCHAR ) : super.columnType( LONGVARCHAR );
case CLOB:
return isUseUnicodeStringTypes() ? columnType( NCLOB ) : super.columnType( CLOB );
// map tinyint to smallint since tinyint is unsigned on HANA
case TINYINT:
return "smallint";
}
return super.columnType( sqlTypeCode );
}
//'double precision' syntax not supported
registerColumnType( Types.DOUBLE, "double" );
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
if ( supportsAsciiStringTypes() ) {
this.useUnicodeStringTypes = configurationService.getSetting(
USE_UNICODE_STRING_TYPES_PARAMETER_NAME,
StandardConverters.BOOLEAN,
useUnicodeStringTypesDefault()
);
}
this.useLegacyBooleanType = configurationService.getSetting(
USE_LEGACY_BOOLEAN_TYPE_PARAMETER_NAME,
StandardConverters.BOOLEAN,
USE_LEGACY_BOOLEAN_TYPE_DEFAULT_VALUE
);
//no explicit precision
registerColumnType(Types.TIMESTAMP, "timestamp");
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamp");
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
// varbinary max length 5000
registerColumnType( Types.BINARY, 5000, "varbinary($l)" );
registerColumnType( Types.VARBINARY, 5000, "varbinary($l)" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, "blob", this )
.withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" )
.build()
);
// for longer values, map to blob
registerColumnType( Types.BINARY, "blob" );
registerColumnType( Types.VARBINARY, "blob" );
//there is no 'char' or 'nchar' type in HANA
registerColumnType( Types.CHAR, "varchar($l)" );
registerColumnType( Types.NCHAR, "nvarchar($l)" );
registerColumnType( Types.VARCHAR, 5000, "varchar($l)" );
registerColumnType( Types.NVARCHAR, 5000, "nvarchar($l)" );
// for longer values map to clob/nclob
registerColumnType( Types.VARCHAR, "clob" );
registerColumnType( Types.NVARCHAR, "nclob" );
// map tinyint to smallint since tinyint is unsigned on HANA
registerColumnType( Types.TINYINT, "smallint" );
registerHibernateType( Types.NCLOB, StandardBasicTypes.MATERIALIZED_NCLOB.getName() );
registerHibernateType( Types.CLOB, StandardBasicTypes.MATERIALIZED_CLOB.getName() );
registerHibernateType( Types.BLOB, StandardBasicTypes.MATERIALIZED_BLOB.getName() );
registerHibernateType( Types.NVARCHAR, StandardBasicTypes.NSTRING.getName() );
registerColumnType( SqlTypes.GEOMETRY, "st_geometry" );
registerColumnType( SqlTypes.POINT, "st_point" );
registerHanaKeywords();
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "st_geometry", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( POINT, "st_point", this ) );
}
@Override
@ -516,7 +559,9 @@ public abstract class AbstractHANADialect extends Dialect {
return false;
}
protected void registerHanaKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "all" );
registerKeyword( "alter" );
registerKeyword( "as" );
@ -888,43 +933,18 @@ public abstract class AbstractHANADialect extends Dialect {
}
if ( supportsAsciiStringTypes() ) {
this.useUnicodeStringTypes = configurationService.getSetting(
USE_UNICODE_STRING_TYPES_PARAMETER_NAME,
StandardConverters.BOOLEAN,
useUnicodeStringTypesDefault()
);
if ( this.isUseUnicodeStringTypes() ) {
registerColumnType( Types.CHAR, "nvarchar($l)" );
registerColumnType( Types.VARCHAR, 5000, "nvarchar($l)" );
// for longer values map to clob/nclob
registerColumnType( Types.VARCHAR, "nclob" );
registerColumnType( Types.CLOB, "nclob" );
}
if ( this.clobTypeDescriptor.getMaxLobPrefetchSize() != maxLobPrefetchSize
|| this.clobTypeDescriptor.isUseUnicodeStringTypes() != this.useUnicodeStringTypes ) {
this.clobTypeDescriptor = new HANAClobJdbcType( maxLobPrefetchSize, this.useUnicodeStringTypes );
}
}
this.useLegacyBooleanType = configurationService.getSetting(USE_LEGACY_BOOLEAN_TYPE_PARAMETER_NAME, StandardConverters.BOOLEAN,
USE_LEGACY_BOOLEAN_TYPE_DEFAULT_VALUE);
if ( this.useLegacyBooleanType ) {
registerColumnType( Types.BOOLEAN, "tinyint" );
}
boolean treatDoubleTypedFieldsAsDecimal = configurationService.getSetting(TREAT_DOUBLE_TYPED_FIELDS_AS_DECIMAL_PARAMETER_NAME, StandardConverters.BOOLEAN,
TREAT_DOUBLE_TYPED_FIELDS_AS_DECIMAL_DEFAULT_VALUE);
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
.getJdbcTypeRegistry();
if (treatDoubleTypedFieldsAsDecimal) {
registerHibernateType( Types.FLOAT, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.REAL, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.DOUBLE, StandardBasicTypes.BIG_DECIMAL.getName() );
typeContributions.getTypeConfiguration().getBasicTypeRegistry()
.register(
new BasicTypeImpl<>(

View File

@ -59,13 +59,12 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
// note that 'real' is double precision on SQL Server, single precision on Sybase
// but 'float' is single precision on Sybase, double precision on SQL Server
switch(jdbcTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return "bit";
case TINYINT:
//'tinyint' is an unsigned type in Sybase and
//SQL Server, holding values in the range 0-255
@ -74,21 +73,19 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
case INTEGER:
//it's called 'int' not 'integer'
return "int";
case DATE:
case TIME:
case TIMESTAMP:
case TIME_WITH_TIMEZONE:
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "datetime";
case BLOB:
return "image";
case CLOB:
case NCLOB:
return "text";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override

View File

@ -9,15 +9,12 @@ package org.hibernate.dialect;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.boot.model.TypeContributions;
@ -26,7 +23,6 @@ import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
@ -46,12 +42,13 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
@ -95,56 +92,36 @@ public class CockroachDialect extends Dialect {
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> typeCodes = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
typeCodes.addAll( List.of(UUID, INTERVAL_SECOND, GEOMETRY, JSON) );
if ( getVersion().isSameOrAfter( 20 ) ) {
typeCodes.add(INET);
}
return typeCodes;
}
@Override
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case TINYINT:
return "smallint"; //no tinyint
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
return "string($l)";
case NCLOB:
case CLOB:
case NCLOB:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "string";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
return "bytes($l)";
case BLOB:
case LONG32VARBINARY:
return "bytes";
case INET:
return "inet";
case UUID:
return "uuid";
case GEOMETRY:
return "geometry";
case INTERVAL_SECOND:
return "interval second($s)";
case JSON:
// Prefer jsonb if possible
return getVersion().isSameOrAfter( 20 ) ? "jsonb" : "json";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
protected String castType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case CHAR:
case NCHAR:
case VARCHAR:
@ -160,19 +137,26 @@ public class CockroachDialect extends Dialect {
case LONG32VARBINARY:
return "bytes";
}
return super.getUnboundedTypeName( jdbcType, javaType );
return super.castType( sqlTypeCode );
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
// The maximum scale for `interval second` is 6 unfortunately so we have to use numeric by default
if ( code == SqlTypes.INTERVAL_SECOND ) {
final Integer scale = size.getScale();
if ( scale == null || scale > 6 ) {
return getTypeName( SqlTypes.NUMERIC, size );
}
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
// Prefer jsonb if possible
if ( getVersion().isSameOrAfter( 20 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "jsonb", this ) );
}
else {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
return super.getTypeName( code, size );
}
@Override

View File

@ -55,6 +55,9 @@ import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.*;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
@ -92,16 +95,16 @@ public class DB2Dialect extends Dialect {
}
public DB2Dialect(DialectResolutionInfo info) {
super(info);
registerDB2Keywords();
super( info );
}
public DB2Dialect(DatabaseVersion version) {
super(version);
registerDB2Keywords();
super( version );
}
private void registerDB2Keywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
//not keywords, at least not in DB2 11,
//but perhaps they were in older versions?
registerKeyword( "current" );
@ -127,27 +130,19 @@ public class DB2Dialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
if ( getDB2Version().isBefore( 11 ) ) {
switch (jdbcTypeCode) {
case BOOLEAN:
// prior to DB2 11, the 'boolean' type existed,
// but was not allowed as a column type
return "smallint";
case BINARY: // should use 'binary' since version 11
case VARBINARY: // should use 'varbinary' since version 11
return "varchar($l) for bit data";
}
}
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
// prior to DB2 11, the 'boolean' type existed,
// but was not allowed as a column type
return getDB2Version().isBefore( 11 ) ? "smallint" : super.columnType( sqlTypeCode );
case TINYINT:
// no tinyint
return "smallint";
case NUMERIC:
// HHH-12827: map them both to the same type to avoid problems with schema update
// Note that 31 is the maximum precision DB2 supports
return super.columnType(DECIMAL);
return columnType( DECIMAL );
case BLOB:
return "blob($l)";
case CLOB:
@ -156,18 +151,25 @@ public class DB2Dialect extends Dialect {
return "timestamp($p)";
case TIME_WITH_TIMEZONE:
return "time";
default:
return super.columnType(jdbcTypeCode);
case VARBINARY:
// should use 'varbinary' since version 11
return getDB2Version().isBefore( 11 ) ? "varchar($l) for bit data" : super.columnType( sqlTypeCode );
}
return super.columnType( sqlTypeCode );
}
@Override
protected void registerDefaultColumnTypes() {
// Note: the 'long varchar' data type was deprecated in DB2 and shouldn't be used anymore
super.registerDefaultColumnTypes();
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getDB2Version().isBefore( 11 ) ) {
// should use 'binary' since version 11
registerColumnType( BINARY, 254, "char($l) for bit data" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, "varchar($l) for bit data", this )
.withTypeCapacity( 254, "char($l) for bit data" )
.build()
);
}
}
@ -272,14 +274,15 @@ public class DB2Dialect extends Dialect {
queryEngine.getTypeConfiguration(),
SqlAstNodeRenderingMode.DEFAULT,
"||",
getCastTypeName(
queryEngine.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.STRING ),
null,
null,
null
),
queryEngine.getTypeConfiguration().getDdlTypeRegistry().getDescriptor( VARCHAR )
.getCastTypeName(
queryEngine.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.STRING ),
null,
null,
null
),
true
)
);
@ -499,7 +502,7 @@ public class DB2Dialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
return selectNullString(sqlType);
}

View File

@ -42,6 +42,14 @@ public class DB2iDialect extends DB2Dialect {
registerKeywords( info );
}
public DB2iDialect() {
this( DatabaseVersion.make(7) );
}
public DB2iDialect(DatabaseVersion version) {
super(version);
}
@Override
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
@ -53,14 +61,6 @@ public class DB2iDialect extends DB2Dialect {
}
}
public DB2iDialect() {
this( DatabaseVersion.make(7) );
}
public DB2iDialect(DatabaseVersion version) {
super(version);
}
@Override
public DatabaseVersion getDB2Version() {
return DB2_LUW_VERSION9;

View File

@ -65,12 +65,12 @@ public class DB2zDialect extends DB2Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
// See https://www.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/wnew/src/tpc/db2z_10_timestamptimezone.html
if ( jdbcTypeCode==TIMESTAMP_WITH_TIMEZONE && getVersion().isAfter(10) ) {
protected String columnType(int sqlTypeCode) {
if ( sqlTypeCode == TIMESTAMP_WITH_TIMEZONE && getVersion().isAfter( 10 ) ) {
// See https://www.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/wnew/src/tpc/db2z_10_timestamptimezone.html
return "timestamp with time zone";
}
return super.columnType(jdbcTypeCode);
return super.columnType( sqlTypeCode );
}
@Override

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.dialect;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.function.CastingConcatFunction;
@ -23,7 +22,6 @@ import org.hibernate.dialect.pagination.DerbyLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.DerbySequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
@ -66,6 +64,9 @@ import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType;
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
import org.hibernate.type.descriptor.jdbc.TimestampJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
@ -105,60 +106,100 @@ public class DerbyDialect extends Dialect {
public DerbyDialect(DatabaseVersion version) {
super(version);
registerDerbyKeywords();
}
public DerbyDialect(DialectResolutionInfo info) {
super(info);
registerDerbyKeywords();
}
@Override
protected String columnType(int jdbcTypeCode) {
if ( jdbcTypeCode == BOOLEAN && getVersion().isBefore( 10, 7 ) ) {
return "smallint";
}
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return getVersion().isBefore( 10, 7 ) ? "smallint" : super.columnType( sqlTypeCode );
case TINYINT:
//no tinyint
return "smallint";
case NUMERIC:
// HHH-12827: map them both to the same type to avoid problems with schema update
// Note that 31 is the maximum precision Derby supports
return super.columnType(DECIMAL);
return columnType( DECIMAL );
case VARBINARY:
return "varchar($l) for bit data";
case LONGVARBINARY:
case LONG32VARBINARY:
return "long varchar for bit data";
case NCHAR:
return columnType( CHAR );
case NVARCHAR:
return columnType( VARCHAR );
case LONGNVARCHAR:
return columnType( LONGVARCHAR );
case LONGVARCHAR:
case LONG32VARCHAR:
return "long varchar";
case BLOB:
return "blob($l)";
case CLOB:
case NCLOB:
return "clob($l)";
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
protected void registerDefaultColumnTypes() {
super.registerDefaultColumnTypes();
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
//long varchar is the right type to use for lengths between 32_672 and 32_700
int maxLongVarcharLength = 32_700;
registerColumnType( VARBINARY, maxLongVarcharLength,"long varchar for bit data" );
registerColumnType( VARCHAR, maxLongVarcharLength, "long varchar" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARBINARY, columnType( BLOB ), columnType( VARBINARY ), this )
.withTypeCapacity( getMaxVarbinaryLength(), columnType( VARBINARY ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGVARBINARY ) )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( VARCHAR, columnType( CLOB ), columnType( VARCHAR ), this )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGVARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NVARCHAR, columnType( CLOB ), columnType( NVARCHAR ), this )
.withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGVARCHAR ) )
.build()
);
registerColumnType( BINARY, 254, "char($l) for bit data" );
registerColumnType( BINARY, getMaxVarcharLength(), "varchar($l) for bit data" );
registerColumnType( BINARY, maxLongVarcharLength, "long varchar for bit data" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BINARY, columnType( BLOB ), columnType( VARBINARY ), this )
.withTypeCapacity( 254, "char($l) for bit data" )
.withTypeCapacity( getMaxVarbinaryLength(), columnType( VARBINARY ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGVARBINARY ) )
.build()
);
// This is the maximum size for the CHAR datatype on Derby
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( CHAR, columnType( CLOB ), columnType( CHAR ), this )
.withTypeCapacity( 254, columnType( CHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGVARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NCHAR, columnType( CLOB ), columnType( NCHAR ), this )
.withTypeCapacity( 254, columnType( NCHAR ) )
.withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) )
.withTypeCapacity( maxLongVarcharLength, columnType( LONGNVARCHAR ) )
.build()
);
}
@Override
@ -166,17 +207,6 @@ public class DerbyDialect extends Dialect {
return 32_672;
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
if ( code == Types.CHAR ) {
// This is the maximum size for the CHAR datatype on Derby
if ( size.getLength() > 254 ) {
return "char(254)";
}
}
return super.getTypeName( code, size );
}
@Override
public int getDefaultDecimalPrecision() {
//this is the maximum allowed in Derby
@ -228,7 +258,8 @@ public class DerbyDialect extends Dialect {
queryEngine.getTypeConfiguration(),
SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER,
"||",
getCastTypeName( stringType, null, null, null ),
queryEngine.getTypeConfiguration().getDdlTypeRegistry().getDescriptor( VARCHAR )
.getCastTypeName( stringType, null, null, null ),
true
)
);
@ -370,6 +401,15 @@ public class DerbyDialect extends Dialect {
case LONG:
case FIXED:
return "cast(trim(cast(?1 as char(254))) as ?2)";
case DATE:
// The maximum length of a date
return "cast(?1 as varchar(10))";
case TIME:
// The maximum length of a time
return "cast(?1 as varchar(8))";
case TIMESTAMP:
// The maximum length of a timestamp
return "cast(?1 as varchar(30))";
}
break;
}
@ -435,7 +475,7 @@ public class DerbyDialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
return DB2Dialect.selectNullString( sqlType );
}
@ -597,7 +637,9 @@ public class DerbyDialect extends Dialect {
throw new NotYetImplementedFor6Exception("format() function not supported on Derby");
}
private void registerDerbyKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "ADD" );
registerKeyword( "ALL" );
registerKeyword( "ALLOCATE" );

View File

@ -36,10 +36,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Pattern;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.NotYetImplementedFor6Exception;
@ -108,8 +106,6 @@ import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.Table;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.procedure.internal.StandardCallableStatementSupport;
@ -150,7 +146,6 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
@ -160,6 +155,9 @@ import org.hibernate.type.descriptor.jdbc.NCharJdbcType;
import org.hibernate.type.descriptor.jdbc.NClobJdbcType;
import org.hibernate.type.descriptor.jdbc.NVarcharJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
@ -189,8 +187,8 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithM
* <p>
* Almost every subclass must, as a bare minimum, override at least:
* <ul>
* <li>{@link #columnType(int)} to define a mapping from JDBC
* {@linkplain Types type codes} to database column types, and
* <li>{@link #registerColumnTypes(TypeContributions, ServiceRegistry)} to define a mapping from SQL
* {@linkplain SqlTypes type codes} to database column types, and
* <li>{@link #initializeFunctionRegistry(QueryEngine)} to register
* mappings for standard HQL functions with the
* {@link org.hibernate.query.sqm.function.SqmFunctionRegistry}.
@ -233,10 +231,7 @@ public abstract class Dialect implements ConversionContext {
private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
//needed for converting precision from decimal to binary digits
private static final double LOG_BASE2OF10 = log(10)/log(2);
private final TypeNames typeNames = new TypeNames();
private final TypeNames hibernateTypeNames = new TypeNames();
protected static final double LOG_BASE2OF10 = log(10)/log(2);
private final Properties properties = new Properties();
private final Set<String> sqlKeywords = new HashSet<>();
@ -259,18 +254,12 @@ public abstract class Dialect implements ConversionContext {
protected Dialect(DatabaseVersion version) {
this.version = version;
beforeRegisteringColumnTypes(version);
registerDefaultColumnTypes();
registerHibernateTypes();
registerDefaultKeywords();
initDefaultProperties();
}
protected Dialect(DialectResolutionInfo info) {
this.version = info.makeCopy();
beforeRegisteringColumnTypes(info);
registerDefaultColumnTypes();
registerHibernateTypes();
registerDefaultKeywords();
registerKeywords(info);
initDefaultProperties();
@ -288,23 +277,6 @@ public abstract class Dialect implements ConversionContext {
Boolean.toString( getDefaultUseGetGeneratedKeys() ) );
}
/**
* Called right before {@link #registerDefaultColumnTypes()}, allowing
* the subclass to do something with the {@link DialectResolutionInfo}.
* <p>
* Take care when overriding this method: it's only called when the
* {@code Dialect} is constructed using {@code Dialect(DialectResolutionInfo)}.
*/
protected void beforeRegisteringColumnTypes(DialectResolutionInfo info) {}
/**
* Called right before {@link #registerDefaultColumnTypes()}.
* <p>
* Take care when overriding this method: it's only called when the
* {@code Dialect} is constructed using {@code Dialect(DatabaseVersion)}.
*/
protected void beforeRegisteringColumnTypes(DatabaseVersion version) {}
/**
* Register ANSI-standard column types using the length limits defined
* by {@link #getMaxVarcharLength()}, {@link #getMaxNVarcharLength()},
@ -312,102 +284,85 @@ public abstract class Dialect implements ConversionContext {
* <p>
* This method is always called when a {@code Dialect} is instantiated.
*/
protected void registerDefaultColumnTypes() {
registerDefaultColumnTypes( getMaxVarcharLength(), getMaxNVarcharLength(), getMaxVarbinaryLength() );
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
ddlTypeRegistry.addDescriptor( simpleSqlType( BOOLEAN ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( TINYINT ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( SMALLINT ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( INTEGER ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( BIGINT ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( FLOAT ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( REAL ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( DOUBLE ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( NUMERIC ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( DECIMAL ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( DATE ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( TIME ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( TIME_WITH_TIMEZONE ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( TIMESTAMP ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( TIMESTAMP_WITH_TIMEZONE ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( CHAR ) );
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( VARCHAR, LONGVARCHAR, VARCHAR )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( LONGVARCHAR, LONGVARCHAR, VARCHAR )
.withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor( simpleSqlType( CLOB ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( NCHAR ) );
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( NVARCHAR, LONGNVARCHAR, NVARCHAR )
.withTypeCapacity( getMaxNVarcharLength(), columnType( NVARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( LONGNVARCHAR, LONGNVARCHAR, NVARCHAR )
.withTypeCapacity( getMaxNVarcharLength(), columnType( NVARCHAR ) )
.build()
);
ddlTypeRegistry.addDescriptor( simpleSqlType( NCLOB ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( BINARY ) );
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( VARBINARY, LONGVARBINARY, VARBINARY )
.withTypeCapacity( getMaxVarbinaryLength(), columnType( VARBINARY ) )
.build()
);
ddlTypeRegistry.addDescriptor(
sqlTypeBuilder( LONGVARBINARY, LONGVARBINARY, VARBINARY )
.withTypeCapacity( getMaxVarbinaryLength(), columnType( VARBINARY ) )
.build()
);
ddlTypeRegistry.addDescriptor( simpleSqlType( BLOB ) );
// by default use the LOB mappings for the "long" types
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32NVARCHAR ) );
ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARBINARY ) );
}
/**
* Register an ANSI-standard column type for each JDBC type defined
* by {@link Types}. These mappings may be overridden by a concrete
* {@code Dialect} by calling {@link #registerColumnType(int,String)}
* from the constructor.
* <p>
* The "long" types {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR}
* and {@link Types#LONGVARBINARY} are considered synonyms for their
* non-{@code LONG} counterparts, with the only difference being that
* a different default length is used: {@link org.hibernate.Length#LONG}
* instead of {@link org.hibernate.Length#DEFAULT}.
* <p>
* This method is aware of the notion of a maximum length for each of
* the types {@link Types#VARCHAR}, {@link Types#NVARCHAR}, and
* {@link Types#VARBINARY}, usually the limits defined by
* {@link #getMaxVarcharLength()}, {@link #getMaxNVarcharLength()},
* and {@link #getMaxVarbinaryLength()}, and registers "long32" types,
* that is, {@link org.hibernate.Length#LONG32} types, for lengths
* exceeding the limits.
* <p>
* Any registrations made by this method may be overridden by calling
* {@link #registerColumnType(int, String)} explicitly. Alternatively,
* the registrations may be customized by overriding
* {@link #getSupportedJdbcTypeCodes()} and {@link #columnType(int)}.
*
* @param maxVarcharLength the maximum length of the {@link Types#VARCHAR} type
* @param maxNVarcharLength the maximum length of the {@link Types#NVARCHAR} type
* @param maxVarBinaryLength the maximum length of the {@link Types#VARBINARY} type
*/
protected void registerDefaultColumnTypes(int maxVarcharLength, int maxNVarcharLength, int maxVarBinaryLength) {
for ( int typeCode : getSupportedJdbcTypeCodes() ) {
switch (typeCode) {
case VARCHAR:
registerColumnType( typeCode, maxVarcharLength, columnType(typeCode) );
// we look up the "long" type under the code LONG32VARCHAR
// which by default returns the CLOB type
registerColumnType( typeCode, columnType(LONG32VARCHAR) );
break;
case NVARCHAR:
registerColumnType( typeCode, maxNVarcharLength, columnType(typeCode) );
// we look up the "long" type under the code LONG32NVARCHAR
// which by default returns the NCLOB type
registerColumnType( typeCode, columnType(LONG32NVARCHAR) );
break;
case VARBINARY:
registerColumnType( typeCode, maxVarBinaryLength, columnType(typeCode) );
// we look up the "long" type under the code LONG32VARBINARY
// which by default returns the BLOB type
registerColumnType( typeCode, columnType(LONG32VARBINARY) );
break;
default:
registerColumnType( typeCode, columnType(typeCode) );
}
}
private DdlTypeImpl simpleSqlType(int sqlTypeCode) {
return new DdlTypeImpl( sqlTypeCode, columnType( sqlTypeCode ), castType( sqlTypeCode ), this );
}
/**
* A list of JDBC types that we expect to be supported on all databases.
*/
private static final List<Integer> ANSI_SQL_TYPES = List.of(
BOOLEAN,
TINYINT, SMALLINT, INTEGER, BIGINT,
REAL, FLOAT, DOUBLE,
NUMERIC, DECIMAL,
DATE,
TIME, TIME_WITH_TIMEZONE,
TIMESTAMP, TIMESTAMP_WITH_TIMEZONE,
CHAR, VARCHAR, CLOB,
NCHAR, NVARCHAR, NCLOB,
BINARY, VARBINARY, BLOB
);
/**
* The JDBC type codes of types supported by this SQL dialect, from the lists
* defined by {@link Types} and {@link SqlTypes}.
* <p>
* This method may be overridden by concrete {@code Dialect}s as an alternative
* to calling {@link #registerColumnType(int, String)}. In this case,
* {@link #columnType(int)} should also be overridden.
* <p>
* Note that {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR} and
* {@link Types#LONGVARBINARY} are considered synonyms for their
* non-{@code LONG} counterparts, and should not be included in the returned
* array.
*
* @return an array of types from {@link SqlTypes}
*
* @see SqlTypes
* @see #columnType(int)
*/
protected List<Integer> getSupportedJdbcTypeCodes() {
return ANSI_SQL_TYPES;
private CapacityDependentDdlType.Builder sqlTypeBuilder(int sqlTypeCode, int biggestSqlTypeCode, int castTypeCode) {
return CapacityDependentDdlType.builder(
sqlTypeCode,
columnType( biggestSqlTypeCode ),
castType( castTypeCode ),
this
);
}
/**
@ -416,16 +371,15 @@ public abstract class Dialect implements ConversionContext {
* name.
* <p>
* This method may be overridden by concrete {@code Dialect}s as an alternative
* to calling {@link #registerColumnType(int,String)}.
* to {@link #registerColumnTypes(TypeContributions, ServiceRegistry)} for simple registrations.
*
* @param jdbcTypeCode a JDBC type code
* @param sqlTypeCode a SQL type code
* @return a column type name, with $l, $p, $s placeholders for length, precision, scale
*
* @see SqlTypes
* @see #getSupportedJdbcTypeCodes()
*/
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return "boolean";
@ -494,57 +448,23 @@ public abstract class Dialect implements ConversionContext {
return "blob";
// by default use the LOB mappings for the "long" types
case LONGVARCHAR:
case LONG32VARCHAR:
return columnType(CLOB);
return columnType( CLOB );
case LONGNVARCHAR:
case LONG32NVARCHAR:
return columnType(NCLOB);
return columnType( NCLOB );
case LONGVARBINARY:
case LONG32VARBINARY:
return columnType(BLOB);
return columnType( BLOB );
default:
throw new IllegalArgumentException("unknown type: " + jdbcTypeCode);
throw new IllegalArgumentException( "unknown type: " + sqlTypeCode );
}
}
protected void registerHibernateTypes() {
// register hibernate types for default use in scalar sqlquery type auto detection
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() );
registerHibernateType( Types.BIT, 64, StandardBasicTypes.LONG.getName() );
registerHibernateType( Types.BIT, 32, StandardBasicTypes.INTEGER.getName() );
registerHibernateType( Types.BIT, 16, StandardBasicTypes.SHORT.getName() );
registerHibernateType( Types.BIT, 8, StandardBasicTypes.BYTE.getName() );
registerHibernateType( Types.BIT, 1, StandardBasicTypes.BOOLEAN.getName() );
registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() );
registerHibernateType( Types.DOUBLE, StandardBasicTypes.DOUBLE.getName() );
registerHibernateType( Types.FLOAT, StandardBasicTypes.DOUBLE.getName() );
registerHibernateType( Types.NUMERIC, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.DECIMAL, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.BIGINT, StandardBasicTypes.LONG.getName() );
registerHibernateType( Types.INTEGER, StandardBasicTypes.INTEGER.getName() );
registerHibernateType( Types.SMALLINT, StandardBasicTypes.SHORT.getName() );
registerHibernateType( Types.TINYINT, StandardBasicTypes.BYTE.getName() );
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.CHAR, StandardBasicTypes.STRING.getName() );
registerHibernateType( Types.VARCHAR, 1, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.VARCHAR, StandardBasicTypes.STRING.getName() );
registerHibernateType( Types.NVARCHAR, StandardBasicTypes.NSTRING.getName() );
registerHibernateType( Types.LONGVARCHAR, StandardBasicTypes.TEXT.getName() );
registerHibernateType( Types.LONGNVARCHAR, StandardBasicTypes.NTEXT.getName() );
registerHibernateType( Types.BINARY, StandardBasicTypes.BINARY.getName() );
registerHibernateType( Types.VARBINARY, StandardBasicTypes.BINARY.getName() );
registerHibernateType( Types.LONGVARBINARY, StandardBasicTypes.IMAGE.getName() );
registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getName() );
registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() );
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() );
registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getName() );
registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getName() );
protected String castType(int sqlTypeCode) {
return columnType( sqlTypeCode );
}
protected void registerDefaultKeywords() {
@ -588,19 +508,6 @@ public abstract class Dialect implements ConversionContext {
}
}
/**
* Useful conversion for databases which represent the
* precision of a float(p) using p expressed in decimal
* digits instead of the usual (standard) binary digits.
*/
protected static Size binaryToDecimalPrecision(int code, Size size) {
return code == Types.FLOAT
&& size != null
&& size.getPrecision() != null
? Size.precision( (int) Math.ceil( size.getPrecision() / LOG_BASE2OF10 ) )
: size;
}
/**
* Render a SQL check condition for a column that represents a boolean value.
*/
@ -1337,7 +1244,7 @@ public abstract class Dialect implements ConversionContext {
*/
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
// by default, not much to do...
registerColumnTypes( typeContributions, serviceRegistry );
final NationalizationSupport nationalizationSupport = getNationalizationSupport();
if ( nationalizationSupport == NationalizationSupport.EXPLICIT ) {
typeContributions.contributeJdbcType( NCharJdbcType.INSTANCE );
@ -1354,183 +1261,6 @@ public abstract class Dialect implements ConversionContext {
}
}
/**
* Get the name of the database type associated with the given
* {@link SqlTypes} typecode, with no length, precision,
* or scale.
*
* @param code The {@link SqlTypes} typecode
* @return the database type name
* @throws HibernateException If no mapping was specified for that type.
*/
public String getRawTypeName(int code) throws HibernateException {
final String result = typeNames.get( code );
if ( result == null ) {
throw new HibernateException( "No default type mapping for (org.hibernate.type.SqlTypes) " + code );
}
//trim off the length/precision/scale
final int paren = result.indexOf('(');
return paren>0 ? result.substring(0, paren) : result;
}
public String getRawTypeName(JdbcType jdbcType) throws HibernateException {
return getRawTypeName( jdbcType.getDefaultSqlTypeCode() );
}
public String getTypeName(JdbcType jdbcType) throws HibernateException {
return getTypeName( jdbcType.getDefaultSqlTypeCode() );
}
public String getTypeName(int code) throws HibernateException {
// explicitly enforce dialect's default precisions
switch ( code ) {
case Types.DECIMAL:
case Types.NUMERIC:
return getTypeName( code, Size.precision( getDefaultDecimalPrecision() ) );
case Types.FLOAT:
case Types.REAL:
return getTypeName( code, Size.precision( getFloatPrecision() ) );
case Types.DOUBLE:
return getTypeName( code, Size.precision( getDoublePrecision() ) );
case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
return getTypeName( code, Size.precision( getDefaultTimestampPrecision() ) );
default:
return getTypeName( code, Size.nil() );
}
}
/**
* Get the name of the database type associated with the given
* {@code org.hibernate.type.SqlTypes} typecode.
*
* @param code {@code org.hibernate.type.SqlTypes} typecode
* @param size the length, precision, scale of the column
*
* @return the database type name
*
*/
public String getTypeName(int code, Size size) throws HibernateException {
String result = typeNames.get( code, size.getLength(), size.getPrecision(), size.getScale() );
if ( result == null ) {
switch ( code ) {
// these are no longer considered separate column types as such
// they're just used to indicate that JavaType.getLongSqlLength()
// should be used by default (and that's already handled by the
// time we get to here)
case Types.LONGVARCHAR:
return getTypeName( Types.VARCHAR, size );
case Types.LONGNVARCHAR:
return getTypeName( Types.NVARCHAR, size );
case Types.LONGVARBINARY:
return getTypeName( Types.VARBINARY, size );
}
throw new HibernateException(
String.format(
"No type mapping for java.sql.Types code: %s, length: %s",
code,
size.getLength()
)
);
}
return result;
}
/**
* Get the name of the database type associated with the given
* {@code SqlTypeDescriptor}.
*
* @param jdbcType the SQL type
* @param size the length, precision, scale of the column
*
* @return the database type name
*
*/
public String getTypeName(JdbcType jdbcType, Size size) {
return getTypeName( jdbcType.getDefaultSqlTypeCode(), size );
}
/**
* Get the name of the database type appropriate for casting operations
* (via the CAST() SQL function) for the given {@link SqlExpressible}
* SQL type.
*
* @return The database type name
*/
public String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
final JdbcMapping jdbcMapping = type.getJdbcMapping();
final JdbcType jdbcType = jdbcMapping.getJdbcType();
final JavaType<?> javaType = jdbcMapping.getJavaTypeDescriptor();
Size size;
if ( length == null && precision == null ) {
return getUnboundedTypeName( jdbcType, javaType );
}
else {
//use the given length/precision/scale
if ( precision != null && scale == null ) {
//needed for cast(x as BigInteger(p))
scale = javaType.getDefaultSqlScale( Dialect.this, jdbcType );
}
size = new Size()
.setLength( length )
.setPrecision( precision )
.setScale( scale );
}
return getTypeName( jdbcType, size );
}
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
Long length = null;
Integer precision = null;
Integer scale = null;
switch ( jdbcType.getDefaultSqlTypeCode() ) {
case VARCHAR:
length = (long) getMaxVarcharLength();
break;
case NVARCHAR:
length = (long) getMaxNVarcharLength();
break;
case VARBINARY:
length = (long) getMaxVarbinaryLength();
break;
}
return getTypeName(
jdbcType,
getSizeStrategy().resolveSize(
jdbcType,
javaType,
precision,
scale,
length
)
);
}
/**
* Subclasses register a type name for the given type code and maximum
* column length. {@code $l} in the type name with be replaced by the
* column length (if appropriate).
*
* @param code The {@link Types} typecode
* @param capacity The maximum length of database type
* @param name The database type name
*/
protected void registerColumnType(int code, long capacity, String name) {
typeNames.put( code, capacity, name );
}
/**
* Subclasses register a type name for the given type code. {@code $l} in
* the type name with be replaced by the column length (if appropriate).
*
* @param code The {@link Types} typecode
* @param name The database type name
*/
protected void registerColumnType(int code, String name) {
typeNames.put( code, name );
}
/**
* The legacy behavior of Hibernate. LOBs are not processed by merge
*/
@ -1679,87 +1409,6 @@ public abstract class Dialect implements ConversionContext {
}
// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the name of the Hibernate {@link Type} associated with the given
* {@link Types} type code.
*
* @param code The {@link Types} type code
* @return The Hibernate {@link Type} name.
* @throws HibernateException If no mapping was specified for that type.
*/
@SuppressWarnings("UnusedDeclaration")
public String getHibernateTypeName(int code) throws HibernateException {
final String result = hibernateTypeNames.get( code );
if ( result == null ) {
throw new HibernateException( "No Hibernate type mapping for java.sql.Types code: " + code );
}
return result;
}
/**
* Whether or not the given type name has been registered for this dialect (including both hibernate type names and
* custom-registered type names).
*
* @param typeName the type name.
*
* @return true if the given string has been registered either as a hibernate type or as a custom-registered one
*/
public boolean isTypeNameRegistered(final String typeName) {
return this.typeNames.containsTypeName( typeName );
}
/**
* Get the name of the Hibernate {@link Type} associated
* with the given {@link Types} typecode with the given storage
* specification parameters.
*
* @param code The {@link Types} typecode
* @param length The datatype length
* @param precision The datatype precision
* @param scale The datatype scale
* @return The Hibernate {@link Type} name.
* @throws HibernateException If no mapping was specified for that type.
*/
public String getHibernateTypeName(int code, Integer length, Integer precision, Integer scale) throws HibernateException {
final String result = hibernateTypeNames.get( code, length.longValue(), precision, scale );
if ( result == null ) {
throw new HibernateException(
String.format(
"No Hibernate type mapping for type [code=%s, length=%s]",
code,
length
)
);
}
return result;
}
/**
* Registers a Hibernate {@link Type} name for the given
* {@link Types} type code and maximum column length.
*
* @param code The {@link Types} typecode
* @param capacity The maximum length of database type
* @param name The Hibernate {@link Type} name
*/
protected void registerHibernateType(int code, long capacity, String name) {
hibernateTypeNames.put( code, capacity, name );
}
/**
* Registers a Hibernate {@link Type} name for the given
* {@link Types} type code.
*
* @param code The {@link Types} typecode
* @param name The Hibernate {@link Type} name
*/
protected void registerHibernateType(int code, String name) {
hibernateTypeNames.put( code, name );
}
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@ -2383,9 +2032,10 @@ public abstract class Dialect implements ConversionContext {
* will be part of a UNION/UNION ALL.
*
* @param sqlType The {@link Types} type code.
* @param typeConfiguration The type configuration
* @return The appropriate select clause value fragment.
*/
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
return "null";
}
@ -3998,7 +3648,7 @@ public abstract class Dialect implements ConversionContext {
case Types.REAL:
// this is almost always the thing we use:
size.setPrecision( javaType.getDefaultSqlPrecision( Dialect.this, jdbcType ) );
if (scale != null && scale!=0) {
if ( scale != null && scale != 0 ) {
throw new IllegalArgumentException("scale has no meaning for floating point numbers");
}
// but if the user explicitly specifies a precision, we need to convert it:
@ -4011,7 +3661,7 @@ public abstract class Dialect implements ConversionContext {
case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
size.setPrecision( javaType.getDefaultSqlPrecision( Dialect.this, jdbcType ) );
if (scale != null && scale!=0) {
if ( scale != null && scale != 0 ) {
throw new IllegalArgumentException("scale has no meaning for timestamps");
}
break;
@ -4019,10 +3669,11 @@ public abstract class Dialect implements ConversionContext {
case Types.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

@ -8,8 +8,6 @@ package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.PessimisticLockException;
@ -60,11 +58,11 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
@ -75,6 +73,8 @@ import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.DOUBLE;
import static org.hibernate.type.SqlTypes.FLOAT;
import static org.hibernate.type.SqlTypes.GEOMETRY;
import static org.hibernate.type.SqlTypes.INTERVAL_SECOND;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARBINARY;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
@ -84,6 +84,7 @@ import static org.hibernate.type.SqlTypes.LONGVARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NUMERIC;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.UUID;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.SqlTypes.VARCHAR;
@ -141,14 +142,6 @@ public class H2Dialect extends Dialect {
? SequenceInformationExtractorLegacyImpl.INSTANCE
: SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES";
registerColumnType( Types.DECIMAL, "numeric($p,$s)" );
if ( version.isSameOrAfter( 1, 4, 197 ) ) {
registerColumnType( SqlTypes.UUID, "uuid" );
registerColumnType( SqlTypes.GEOMETRY, "geometry" );
if ( version.isSameOrAfter( 1, 4, 198 ) ) {
registerColumnType( SqlTypes.INTERVAL_SECOND, "interval second($p,$s)" );
}
}
}
else {
this.sequenceInformationExtractor = SequenceInformationExtractorNoOpImpl.INSTANCE;
@ -177,29 +170,30 @@ public class H2Dialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
if ( jdbcTypeCode == NUMERIC && getVersion().isBefore(2) ) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
// prior to version 2.0, H2 reported NUMERIC columns as DECIMAL,
// which caused problems for schema update tool
return super.columnType(DECIMAL);
}
switch (jdbcTypeCode) {
case LONG32VARCHAR:
case NUMERIC:
return getVersion().isBefore( 2 ) ? columnType( DECIMAL ) : super.columnType( sqlTypeCode );
case NCHAR:
return columnType( CHAR );
case NVARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
return "varchar";
case LONGVARCHAR:
case LONG32VARCHAR:
return columnType( VARCHAR );
case LONGVARBINARY:
case LONG32VARBINARY:
return "varbinary";
case ARRAY:
return "array";
default:
return super.columnType(jdbcTypeCode);
return columnType( VARBINARY );
}
return super.columnType( sqlTypeCode );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
protected String castType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case CHAR:
case NCHAR:
return "char";
@ -216,14 +210,24 @@ public class H2Dialect extends Dialect {
case LONG32VARBINARY:
return "varbinary";
}
return super.getUnboundedTypeName( jdbcType, javaType );
return super.castType( sqlTypeCode );
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> typeCodes = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
typeCodes.add(ARRAY);
return typeCodes;
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getVersion().isBefore( 2 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( ARRAY, "array", this ) );
}
if ( getVersion().isSameOrAfter( 1, 4, 197 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
if ( getVersion().isSameOrAfter( 1, 4, 198 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INTERVAL_SECOND, "interval second($p,$s)", this ) );
}
}
}
@Override

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
@ -51,25 +49,11 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
public HANAColumnStoreDialect(DatabaseVersion version) {
super( version );
if ( version.isSameOrAfter( 4 ) ) {
registerColumnType( Types.CHAR, "nvarchar($l)" );
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "nvarchar($l)" );
}
// for longer values map to clob/nclob
registerColumnType( Types.VARCHAR, "nclob" );
registerColumnType( Types.CLOB, "nclob" );
registerHibernateType( Types.CLOB, StandardBasicTypes.MATERIALIZED_NCLOB.getName() );
registerHibernateType( Types.NCHAR, StandardBasicTypes.NSTRING.getName() );
registerHibernateType( Types.CHAR, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.CHAR, 5000, StandardBasicTypes.NSTRING.getName() );
registerHibernateType( Types.VARCHAR, StandardBasicTypes.NSTRING.getName() );
registerHibernateType( Types.LONGVARCHAR, StandardBasicTypes.NTEXT.getName() );
// register additional keywords
registerHanaCloudKeywords();
}
@Override
public boolean isUseUnicodeStringTypes() {
return getVersion().isSameOrAfter( 4 ) || super.isUseUnicodeStringTypes();
}
@Override
@ -77,7 +61,9 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
return 5000;
}
private void registerHanaCloudKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "array" );
registerKeyword( "at" );
registerKeyword( "authorization" );

View File

@ -67,6 +67,7 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHSQLDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
@ -92,8 +93,7 @@ public class HSQLDialect extends Dialect {
);
public HSQLDialect(DialectResolutionInfo info) {
this( info.makeCopy() );
registerKeywords( info );
super( info );
}
public HSQLDialect() {
@ -102,14 +102,18 @@ public class HSQLDialect extends Dialect {
public HSQLDialect(DatabaseVersion version) {
super( version.isSame( 1, 8 ) ? reflectedVersion( version ) : version );
}
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
if ( getVersion().isSameOrAfter( 2, 5 ) ) {
registerKeyword( "period" );
}
}
@Override
protected String columnType(int jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
// Note that all floating point types are synonyms for 'double'
// Note that the HSQL type 'longvarchar' and 'longvarbinary' are
@ -117,28 +121,25 @@ public class HSQLDialect extends Dialect {
// But using these types results in schema validation issue as
// described in HHH-9693.
//HSQL has no 'nclob' type, but 'clob' is Unicode (See HHH-10364)
if ( jdbcTypeCode==NCLOB ) {
jdbcTypeCode = CLOB;
switch ( sqlTypeCode ) {
//HSQL has no 'nclob' type, but 'clob' is Unicode (See HHH-10364)
case NCLOB:
return "clob";
}
if ( getVersion().isBefore( 2 ) ) {
switch (jdbcTypeCode) {
switch ( sqlTypeCode ) {
case NUMERIC:
// Older versions of HSQL did not accept
// precision for the 'numeric' type
return "numeric";
// Older versions of HSQL had no lob support
case BLOB:
return "longvarbinary";
case CLOB:
return "longvarchar";
}
}
return super.columnType(jdbcTypeCode);
return super.columnType( sqlTypeCode );
}
@Override
@ -468,7 +469,7 @@ public class HSQLDialect extends Dialect {
} );
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
String literal;
switch ( sqlType ) {
case Types.LONGVARCHAR:

View File

@ -11,8 +11,6 @@ import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.LockOptions;
import org.hibernate.PessimisticLockException;
@ -42,8 +40,6 @@ import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.sqm.CastType;
import org.hibernate.query.sqm.IntervalType;
@ -73,6 +69,9 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JsonJdbcType;
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
@ -107,20 +106,25 @@ public class MySQLDialect extends Dialect {
}
};
private int maxVarcharLength;
private int maxVarbinaryLength;
private final int maxVarcharLength;
private final int maxVarbinaryLength;
public MySQLDialect() {
this( DatabaseVersion.make( 5, 0 ) );
}
public MySQLDialect(DatabaseVersion version) {
super(version);
super( version );
registerKeyword( "key" );
maxVarcharLength = maxVarcharLength( getMySQLVersion(), 4 ); //conservative assumption
maxVarbinaryLength = maxVarbinaryLength( getMySQLVersion() );
}
public MySQLDialect(DialectResolutionInfo info) {
super(info);
super( info );
int bytesPerCharacter = getCharacterSetBytesPerCharacter( info.getDatabaseMetadata() );
maxVarcharLength = maxVarcharLength( getMySQLVersion(), bytesPerCharacter );
maxVarbinaryLength = maxVarbinaryLength( getMySQLVersion() );
}
@Override
@ -149,40 +153,18 @@ public class MySQLDialect extends Dialect {
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> typeCodes = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
typeCodes.add(GEOMETRY);
if ( getMySQLVersion().isBefore( 5, 7 ) ) {
// MySQL 5.7 brings JSON native support with a dedicated datatype
// https://dev.mysql.com/doc/refman/5.7/en/json.html
typeCodes.add(JSON);
}
return typeCodes;
}
@Override
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
// HHH-6935: Don't use "boolean" i.e. tinyint(1) due to JDBC ResultSetMetaData
return "bit";
case TIMESTAMP:
return getMySQLVersion().isBefore( 5, 7 )
? "datetime" : "datetime($p)";
return getMySQLVersion().isBefore( 5, 7 ) ? "datetime" : "datetime($p)";
case TIMESTAMP_WITH_TIMEZONE:
return getMySQLVersion().isBefore( 5, 7 )
? "timestamp" : "timestamp($p)";
return getMySQLVersion().isBefore( 5, 7 ) ? "timestamp" : "timestamp($p)";
case NUMERIC:
// it's just a synonym
return super.columnType(DECIMAL);
case JSON:
return "json";
case GEOMETRY:
return "geometry";
return columnType( DECIMAL );
// the maximum long LOB length is 4_294_967_295, bigger than any Java string
case BLOB:
return "longblob";
@ -190,28 +172,61 @@ public class MySQLDialect extends Dialect {
case CLOB:
return "longtext";
}
return super.columnType(jdbcTypeCode);
return super.columnType( sqlTypeCode );
}
@Override
protected void beforeRegisteringColumnTypes(DialectResolutionInfo info) {
// we need to remember the character set before calling getMaxVarcharLength()
// we could not do this earlier because we get called from the constructor
// of the superclass, before our own constructor has run
int bytesPerCharacter = getCharacterSetBytesPerCharacter( info.getDatabaseMetadata() );
maxVarcharLength = maxVarcharLength( getMySQLVersion(), bytesPerCharacter );
maxVarbinaryLength = maxVarbinaryLength( getMySQLVersion() );
protected String castType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
case BIT:
//special case for casting to Boolean
return "unsigned";
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
//MySQL doesn't let you cast to INTEGER/BIGINT/TINYINT
return "signed";
case FLOAT:
case REAL:
case DOUBLE:
//MySQL doesn't let you cast to DOUBLE/FLOAT
//but don't just return 'decimal' because
//the default scale is 0 (no decimal places)
return "decimal($p,$s)";
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
case LONG32VARCHAR:
case LONG32NVARCHAR:
//MySQL doesn't let you cast to TEXT/LONGTEXT
return "char";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
//MySQL doesn't let you cast to BLOB/TINYBLOB/LONGBLOB
return "binary";
}
return super.castType( sqlTypeCode );
}
@Override
protected void beforeRegisteringColumnTypes(DatabaseVersion version) {
maxVarcharLength = maxVarcharLength( getMySQLVersion(), 4 ); //conservative assumption
maxVarbinaryLength = maxVarbinaryLength( getMySQLVersion() );
}
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
@Override
protected void registerDefaultColumnTypes() {
super.registerDefaultColumnTypes();
if ( getMySQLVersion().isSameOrAfter( 5, 7 ) ) {
// MySQL 5.7 brings JSON native support with a dedicated datatype
// https://dev.mysql.com/doc/refman/5.7/en/json.html
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
// MySQL has approximately one million text and blob types. We have
// already registered longtext + longblob via the regular method,
@ -221,32 +236,98 @@ public class MySQLDialect extends Dialect {
final int maxLobLen = 65_535;
final int maxMediumLobLen = 16_777_215;
registerColumnType( VARCHAR, maxMediumLobLen, "mediumtext" );
final CapacityDependentDdlType.Builder varcharBuilder = CapacityDependentDdlType.builder(
VARCHAR,
columnType( CLOB ),
"char",
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) {
registerColumnType( VARCHAR, maxLobLen, "text" );
varcharBuilder.withTypeCapacity( maxLobLen, "text" );
}
ddlTypeRegistry.addDescriptor( varcharBuilder.build() );
registerColumnType( NVARCHAR, maxMediumLobLen, "mediumtext" );
if ( getMaxNVarcharLength() < maxLobLen ) {
registerColumnType( NVARCHAR, maxLobLen, "text" );
final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder(
NVARCHAR,
columnType( NCLOB ),
"char",
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) {
nvarcharBuilder.withTypeCapacity( maxLobLen, "text" );
}
ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() );
registerColumnType( VARBINARY, maxMediumLobLen, "mediumblob" );
if ( getMaxVarbinaryLength() < maxLobLen ) {
registerColumnType( VARBINARY, maxLobLen, "blob" );
final CapacityDependentDdlType.Builder varbinaryBuilder = CapacityDependentDdlType.builder(
VARBINARY,
columnType( BLOB ),
"binary",
this
)
.withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumblob" );
if ( getMaxVarcharLength() < maxLobLen ) {
varbinaryBuilder.withTypeCapacity( maxLobLen, "blob" );
}
ddlTypeRegistry.addDescriptor( varbinaryBuilder.build() );
registerColumnType( BLOB, maxMediumLobLen, "mediumblob" );
registerColumnType( BLOB, maxLobLen, "blob" );
registerColumnType( BLOB, maxTinyLobLen, "tinyblob" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( LONGVARBINARY, columnType( BLOB ), "binary", this )
.withTypeCapacity( maxTinyLobLen, "tinyblob" )
.withTypeCapacity( maxMediumLobLen, "mediumblob" )
.withTypeCapacity( maxLobLen, "blob" )
.build()
);
registerColumnType( CLOB, maxMediumLobLen, "mediumtext" );
registerColumnType( CLOB, maxLobLen, "text" );
registerColumnType( CLOB, maxTinyLobLen, "tinytext" );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( LONG32VARBINARY, columnType( BLOB ), "binary", this ) );
registerColumnType( NCLOB, maxMediumLobLen, "mediumtext" );
registerColumnType( NCLOB, maxLobLen, "text" );
registerColumnType( NCLOB, maxTinyLobLen, "tinytext" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( LONGVARCHAR, columnType( CLOB ), "char", this )
.withTypeCapacity( maxTinyLobLen, "tinytext" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" )
.withTypeCapacity( maxLobLen, "text" )
.build()
);
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( LONG32VARCHAR, columnType( CLOB ), "char", this ) );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( LONGNVARCHAR, columnType( NCLOB ), "char", this )
.withTypeCapacity( maxTinyLobLen, "tinytext" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" )
.withTypeCapacity( maxLobLen, "text" )
.build()
);
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( LONG32NVARCHAR, columnType( CLOB ), "char", this ) );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( BLOB, columnType( BLOB ), "binary", this )
.withTypeCapacity( maxTinyLobLen, "tinyblob" )
.withTypeCapacity( maxMediumLobLen, "mediumblob" )
.withTypeCapacity( maxLobLen, "blob" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( CLOB, columnType( CLOB ), "char", this )
.withTypeCapacity( maxTinyLobLen, "tinytext" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" )
.withTypeCapacity( maxLobLen, "text" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( NCLOB, columnType( NCLOB ), "char", this )
.withTypeCapacity( maxTinyLobLen, "tinytext" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" )
.withTypeCapacity( maxLobLen, "text" )
.build()
);
}
protected static int getCharacterSetBytesPerCharacter(DatabaseMetaData databaseMetaData) {
@ -820,72 +901,6 @@ public class MySQLDialect extends Dialect {
return 64;
}
@Override
public String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
final JdbcMapping jdbcMapping = type.getJdbcMapping();
final JdbcType jdbcType = jdbcMapping.getJdbcType();
final JavaType<?> javaType = jdbcMapping.getJavaTypeDescriptor();
switch ( jdbcType.getDefaultSqlTypeCode() ) {
case Types.INTEGER:
case Types.BIGINT:
case Types.SMALLINT:
case Types.TINYINT:
//MySQL doesn't let you cast to INTEGER/BIGINT/TINYINT
return "signed";
case Types.BIT:
//special case for casting to Boolean
return "unsigned";
case Types.FLOAT:
case Types.DOUBLE:
case Types.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)
return String.format(
"decimal(%d, %d)",
precision == null ? javaType.getDefaultSqlPrecision( this, jdbcType ) : precision,
scale == null ? javaType.getDefaultSqlScale( this, jdbcType ) : scale
);
case Types.VARBINARY:
case Types.LONGVARBINARY:
//MySQL doesn't let you cast to BLOB/TINYBLOB/LONGBLOB
if ( length == null ) {
return "binary";
}
return String.format( "binary(%d)", length );
case Types.VARCHAR:
case Types.LONGVARCHAR:
//MySQL doesn't let you cast to TEXT/LONGTEXT
if ( length == null ) {
return "char";
}
return String.format( "char(%d)", length );
default:
return super.getCastTypeName( type, length, precision, scale );
}
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "char";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
return "binary";
}
return super.getUnboundedTypeName( jdbcType, javaType );
}
@Override
public boolean supportsCurrentTimestampSelection() {
return true;

View File

@ -11,8 +11,6 @@ import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -93,6 +91,8 @@ import static org.hibernate.query.sqm.TemporalUnit.SECOND;
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.type.SqlTypes.*;
@ -549,68 +549,53 @@ public class OracleDialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
//note: the 'long' type is deprecated
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
// still, after all these years...
return "number(1,0)";
case VARCHAR:
return getVersion().isBefore( 9 )
? "varchar2($l)": "varchar2($l char)";
case NVARCHAR:
return "nvarchar2($l)";
case BIGINT:
return "number(19,0)";
case SMALLINT:
return "number(5,0)";
case TINYINT:
return "number(3,0)";
case SMALLINT:
return "number(5,0)";
case INTEGER:
return "number(10,0)";
case BIGINT:
return "number(19,0)";
case REAL:
// Oracle's 'real' type is actually double precision
return "float(24)";
case NUMERIC:
case DECIMAL:
// Note that 38 is the maximum precision Oracle supports
return "number($p,$s)";
case DATE:
case TIME:
return "date";
case TIMESTAMP:
// the only difference between date and timestamp
// on Oracle is that date has no fractional seconds
return getVersion().isBefore( 9 )
? "date" : "timestamp($p)";
case TIME_WITH_TIMEZONE:
return getVersion().isBefore( 9 )
? "date" : "timestamp($p) with time zone";
case TIMESTAMP_WITH_TIMEZONE:
return getVersion().isBefore( 9 ) ? "date" : super.columnType( sqlTypeCode );
case VARCHAR:
return getVersion().isBefore( 9 ) ? "varchar2($l)" : "varchar2($l char)";
case NVARCHAR:
return "nvarchar2($l)";
case BINARY:
case VARBINARY:
return "raw($l)";
case GEOMETRY:
return "MDSYS.SDO_GEOMETRY";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> list = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getVersion().isSameOrAfter( 10 ) ) {
list.add(GEOMETRY);
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "MDSYS.SDO_GEOMETRY", this ) );
}
return list;
}
@Override
@ -754,9 +739,9 @@ public class OracleDialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
if ( getVersion().isSameOrAfter( 9 ) ) {
return super.getSelectClauseNullString(sqlType);
return super.getSelectClauseNullString( sqlType, typeConfiguration );
}
else {
switch(sqlType) {

View File

@ -12,7 +12,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
@ -20,7 +19,6 @@ import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.PessimisticLockException;
@ -34,7 +32,6 @@ import org.hibernate.dialect.pagination.LimitOffsetLimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
@ -67,7 +64,6 @@ import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
@ -75,6 +71,10 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
@ -126,66 +126,43 @@ public class PostgreSQLDialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case TINYINT:
// no tinyint, not even in Postgres 11
return "smallint";
case BINARY:
return "bytea";
case BLOB:
case CLOB:
// use oid as the blob type on Postgres because
// the JDBC driver is rubbish
return "oid";
// there are no nchar/nvarchar types in Postgres
case NCHAR:
return super.columnType(CHAR);
return columnType( CHAR );
case NVARCHAR:
return super.columnType(VARCHAR);
// since there's no real difference between TEXT and VARCHAR,
// except for the length limit, we can just use 'text' for the
// "long" string types
return columnType( VARCHAR );
case LONGVARCHAR:
case LONG32VARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
return "text";
// use bytea as the "long" binary type (that there is no
// real VARBINARY type in Postgres, so we always use this)
case BLOB:
case CLOB:
case NCLOB:
return "oid";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
return "bytea";
case INET:
return "inet";
case UUID:
return "uuid";
case GEOMETRY:
return "geometry";
case JSON:
// Prefer jsonb if possible
return getVersion().isSameOrAfter( 9, 4 )
? "jsonb" : "json";
case INTERVAL_SECOND:
return "interval second($s)";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
protected String castType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
case LONG32VARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
return "text";
case BINARY:
@ -194,20 +171,31 @@ public class PostgreSQLDialect extends Dialect {
case LONG32VARBINARY:
return "bytea";
}
return super.getUnboundedTypeName( jdbcType, javaType );
return super.castType( sqlTypeCode );
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> typeCodes = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
typeCodes.addAll( List.of(INET, INTERVAL_SECOND, GEOMETRY) );
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
if ( getVersion().isSameOrAfter( 8, 2 ) ) {
typeCodes.add(UUID);
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
// Prefer jsonb if possible
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "jsonb", this ) );
}
else {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
}
}
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
typeCodes.add(JSON);
}
return typeCodes;
}
@Override
@ -218,20 +206,7 @@ public class PostgreSQLDialect extends Dialect {
@Override
public int getMaxVarbinaryLength() {
//postgres has no varbinary-like type
return -1;
}
@Override
public String getTypeName(int code, Size size) throws HibernateException {
// The maximum scale for `interval second` is 6 unfortunately so we have to use numeric by default
switch ( code ) {
case INTERVAL_SECOND:
final Integer scale = size.getScale();
if ( scale == null || scale > 6 ) {
return getTypeName( NUMERIC, size );
}
}
return super.getTypeName( code, size );
return Integer.MAX_VALUE;
}
@Override
@ -627,9 +602,9 @@ public class PostgreSQLDialect extends Dialect {
}
@Override
public String getSelectClauseNullString(int sqlType) {
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
// Workaround for postgres bug #1453
return "null::" + getRawTypeName( sqlType );
return "null::" + typeConfiguration.getDdlTypeRegistry().getDescriptor( sqlType ).getRawTypeName();
}
@Override

View File

@ -52,20 +52,18 @@ import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import jakarta.persistence.TemporalType;
@ -94,95 +92,95 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
public SQLServerDialect(DatabaseVersion version) {
super(version);
exporter = createSequenceExporter(version);
registerSqlServerKeywords();
}
public SQLServerDialect(DialectResolutionInfo info) {
super(info);
exporter = createSequenceExporter(info);
registerSqlServerKeywords();
}
private StandardSequenceExporter createSequenceExporter(DatabaseVersion version) {
return version.isSameOrAfter(11) ? new SqlServerSequenceExporter(this) : null;
}
private void registerSqlServerKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "top" );
registerKeyword( "key" );
}
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
List<Integer> list = new ArrayList<>( super.getSupportedJdbcTypeCodes() );
if ( getVersion().isSameOrAfter( 10 ) ) {
list.add(GEOMETRY);
protected String columnType(int sqlTypeCode) {
// there is no 'double' type in SQL server
// but 'float' is double precision by default
if ( sqlTypeCode == DOUBLE ) {
return "float";
}
return list;
}
@Override
protected String columnType(int jdbcTypeCode) {
if ( getVersion().isSameOrAfter( 10 ) ) {
switch (jdbcTypeCode) {
case DATE:
return "date";
case TIME:
return "time";
case TIMESTAMP:
return"datetime2($p)";
case TIMESTAMP_WITH_TIMEZONE:
return "datetimeoffset($p)";
}
}
if ( getVersion().isSameOrAfter(9) ) {
// Prefer 'varchar(max)' and 'varbinary(max)' to
// the deprecated TEXT and IMAGE types. Note that
// the length of a VARCHAR or VARBINARY column must
// be either between 1 and 8000 or exactly MAX, and
// the length of an NVARCHAR column must be either
// between 1 and 4000 or exactly MAX. (HHH-3965)
switch (jdbcTypeCode) {
case BLOB:
return "varbinary(max)";
if ( getVersion().isSameOrAfter( 9 ) ) {
switch ( sqlTypeCode ) {
// Prefer 'varchar(max)' and 'varbinary(max)' to
// the deprecated TEXT and IMAGE types. Note that
// the length of a VARCHAR or VARBINARY column must
// be either between 1 and 8000 or exactly MAX, and
// the length of an NVARCHAR column must be either
// between 1 and 4000 or exactly MAX. (HHH-3965)
case LONGVARCHAR:
case LONG32VARCHAR:
case CLOB:
return "varchar(max)";
case LONGNVARCHAR:
case LONG32NVARCHAR:
case NCLOB:
return "nvarchar(max)";
case LONGVARBINARY:
case LONG32VARBINARY:
case BLOB:
return "varbinary(max)";
case DATE:
return getVersion().isSameOrAfter( 10 ) ? "date" : super.columnType( sqlTypeCode );
case TIME:
return getVersion().isSameOrAfter( 10 ) ? "time" : super.columnType( sqlTypeCode );
case TIMESTAMP:
return getVersion().isSameOrAfter( 10 ) ? "datetime2($p)" : super.columnType( sqlTypeCode );
case TIMESTAMP_WITH_TIMEZONE:
return getVersion().isSameOrAfter( 10 ) ? "datetimeoffset($p)" : super.columnType( sqlTypeCode );
}
}
switch (jdbcTypeCode) {
case DOUBLE:
// there is no 'double' type in SQL server
// but 'float' is double precision by default
return "float";
case GEOMETRY:
return "geometry";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
case VARCHAR:
case LONGVARCHAR:
case LONG32VARCHAR:
return "varchar(max)";
case NVARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
return "nvarchar(max)";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
return "varbinary(max)";
protected String castType(int sqlTypeCode) {
if ( getVersion().isSameOrAfter( 9 ) ) {
switch ( sqlTypeCode ) {
case VARCHAR:
case LONGVARCHAR:
case LONG32VARCHAR:
case CLOB:
return "varchar(max)";
case NVARCHAR:
case LONGNVARCHAR:
case LONG32NVARCHAR:
case NCLOB:
return "nvarchar(max)";
case VARBINARY:
case LONGVARBINARY:
case LONG32VARBINARY:
case BLOB:
return "varbinary(max)";
}
}
return super.castType( sqlTypeCode );
}
@Override
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getVersion().isSameOrAfter( 10 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
}
return super.getUnboundedTypeName( jdbcType, javaType );
}
@Override

View File

@ -32,7 +32,6 @@ import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.SemanticException;
@ -48,8 +47,6 @@ import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import jakarta.persistence.TemporalType;
@ -75,7 +72,7 @@ public class SpannerDialect extends Dialect {
private static final UniqueDelegate NOOP_UNIQUE_DELEGATE = new DoNothingUniqueDelegate();
public SpannerDialect() {
super();
super( ZERO_VERSION );
}
public SpannerDialect(DialectResolutionInfo info) {
@ -83,55 +80,53 @@ public class SpannerDialect extends Dialect {
}
@Override
protected String columnType(int jdbcTypeCode) {
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
return "bool";
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
return "int64";
case REAL:
case FLOAT:
case DOUBLE:
case DECIMAL:
case NUMERIC:
return "float64";
//there is no time type of any kind
case TIME:
//timestamp does not accept precision
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
return "timestamp";
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
return "string($l)";
case BINARY:
case VARBINARY:
return "bytes($l)";
case CLOB:
case NCLOB:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "string(max)";
case BINARY:
case VARBINARY:
case LONGVARBINARY:
return "bytes($l)";
case BLOB:
case LONG32VARBINARY:
return "bytes(max)";
default:
return super.columnType(jdbcTypeCode);
}
return super.columnType( sqlTypeCode );
}
@Override
public String getUnboundedTypeName(JdbcType jdbcType, JavaType<?> javaType) {
switch ( jdbcType.getDefaultSqlTypeCode() ) {
protected String castType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case CHAR:
case NCHAR:
case VARCHAR:
@ -147,7 +142,7 @@ public class SpannerDialect extends Dialect {
case LONG32VARBINARY:
return "bytes";
}
return super.getUnboundedTypeName( jdbcType, javaType );
return super.castType( sqlTypeCode );
}
@Override
@ -162,11 +157,6 @@ public class SpannerDialect extends Dialect {
return 10_485_760;
}
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
@Override
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
@ -826,19 +816,6 @@ public class SpannerDialect extends Dialect {
/* Type conversion and casting */
@Override
public String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
switch ( type.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode() ) {
case VARCHAR:
case NVARCHAR:
return "string";
case VARBINARY:
return "bytes";
}
//Spanner doesn't let you specify a length in cast() types
return super.getRawTypeName( type.getJdbcMapping().getJdbcType() );
}
/**
* A no-op {@link Exporter} which is responsible for returning empty Create and Drop SQL strings.
*

View File

@ -39,6 +39,8 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.TimestampJdbcType;
import org.hibernate.type.descriptor.jdbc.TinyIntJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import jakarta.persistence.TemporalType;
@ -78,62 +80,61 @@ public class SybaseASEDialect extends SybaseDialect {
public SybaseASEDialect(DatabaseVersion version) {
super(version);
ansiNull = false;
registerSybaseKeywords();
}
public SybaseASEDialect(DialectResolutionInfo info) {
super(info);
ansiNull = isAnsiNull( info.getDatabaseMetadata() );
registerSybaseKeywords();
}
@Override
protected String columnType(int jdbcTypeCode) {
if ( jdbcTypeCode == BIGINT && getVersion().isBefore( 15 ) ) {
// Sybase ASE didn't introduce 'bigint' until version 15.0
return "numeric(19,0)";
}
if ( getVersion().isSameOrAfter( 12 ) ) {
// 'date' and 'time' were introduced in version 12
// note: 'timestamp' is something weird on ASE,
// not what we're looking for here!
switch (jdbcTypeCode) {
case DATE:
return "date";
case TIME:
return "time";
}
}
switch (jdbcTypeCode) {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
// On Sybase ASE, the 'bit' type cannot be null,
// and cannot have indexes (while we don't use
// tinyint to store signed bytes, we can use it
// to store boolean values)
return "tinyint";
default:
return super.columnType(jdbcTypeCode);
case BIGINT:
// Sybase ASE didn't introduce 'bigint' until version 15.0
return getVersion().isBefore( 15 ) ? "numeric(19,0)" : super.columnType( sqlTypeCode );
case DATE:
return getVersion().isSameOrAfter( 12 ) ? "date" : super.columnType( sqlTypeCode );
case TIME:
return getVersion().isSameOrAfter( 12 ) ? "time" : super.columnType( sqlTypeCode );
}
return super.columnType( sqlTypeCode );
}
@Override
protected void registerDefaultColumnTypes() {
super.registerDefaultColumnTypes();
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
// According to Wikipedia bigdatetime and bigtime were added in 15.5
// But with jTDS we can't use them as the driver can't handle the types
if ( getVersion().isSameOrAfter( 15, 5 ) && !jtdsDriver ) {
registerColumnType( DATE, "bigdatetime" );
registerColumnType( DATE, 3, "datetime" );
registerColumnType( TIME, "bigtime" );
registerColumnType( TIME, 3, "datetime" );
registerColumnType( TIMESTAMP, "bigdatetime" );
registerColumnType( TIMESTAMP, 3, "datetime" );
registerColumnType( TIMESTAMP_WITH_TIMEZONE, "bigdatetime" );
registerColumnType( TIMESTAMP_WITH_TIMEZONE, 3, "datetime" );
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( DATE, "bigdatetime", "bigdatetime", this )
.withTypeCapacity( 3, "datetime" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( TIME, "bigdatetime", "bigdatetime", this )
.withTypeCapacity( 3, "datetime" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( TIMESTAMP, "bigdatetime", "bigdatetime", this )
.withTypeCapacity( 3, "datetime" )
.build()
);
ddlTypeRegistry.addDescriptor(
CapacityDependentDdlType.builder( TIMESTAMP_WITH_TIMEZONE, "bigdatetime", "bigdatetime", this )
.withTypeCapacity( 3, "datetime" )
.build()
);
}
}
@ -282,7 +283,9 @@ public class SybaseASEDialect extends SybaseDialect {
}
}
private void registerSybaseKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
registerKeyword( "add" );
registerKeyword( "all" );
registerKeyword( "alter" );

View File

@ -76,14 +76,6 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
public SybaseDialect(DialectResolutionInfo info) {
super(info);
}
@Override
protected void beforeRegisteringColumnTypes(DialectResolutionInfo info) {
// we need to check init the jtdsDriver field here,
// because we need it in the registerDefaultColumnTypes()
// of the subclass, which is called from the superclass
// constructor, before our constructor has been called
jtdsDriver = info.getDriverName() != null
&& info.getDriverName().contains( "jTDS" );
}

View File

@ -36,12 +36,10 @@ public class TiDBDialect extends MySQLDialect {
public TiDBDialect(DatabaseVersion version) {
super(version);
registerKeywords();
}
public TiDBDialect(DialectResolutionInfo info) {
super(info);
registerKeywords();
}
@Override
@ -50,7 +48,9 @@ public class TiDBDialect extends MySQLDialect {
return VERSION57;
}
private void registerKeywords() {
@Override
protected void registerDefaultKeywords() {
super.registerDefaultKeywords();
// TiDB implemented 'Window Functions' of MySQL 8, so the following keywords are reserved.
registerKeyword("CUME_DIST");
registerKeyword("DENSE_RANK");

View File

@ -13,7 +13,6 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.CastType;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -55,12 +54,13 @@ public class CastingConcatFunction extends AbstractSqmSelfRenderingFunctionDescr
this.concatOperator = concatOperator;
this.needsCastWrapper = needsCastWrapper;
this.argumentRenderingMode = argumentRenderingMode;
this.concatArgumentCastType = dialect.getCastTypeName(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING ),
null,
null,
null
);
this.concatArgumentCastType = typeConfiguration.getDdlTypeRegistry().getDescriptor( SqlTypes.VARCHAR )
.getCastTypeName(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING ),
null,
null,
null
);
}
@Override

View File

@ -37,6 +37,7 @@ import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -83,15 +84,16 @@ public class TemporaryTable implements Exportable, Contributable {
}
this.dialect = dialect;
if ( dialect.getSupportedTemporaryTableKind() == TemporaryTableKind.PERSISTENT ) {
final BasicType<UUID> uuidType = entityDescriptor.getEntityPersister()
final TypeConfiguration typeConfiguration = entityDescriptor.getEntityPersister()
.getFactory()
.getTypeConfiguration()
.getTypeConfiguration();
final BasicType<UUID> uuidType = typeConfiguration
.getBasicTypeForJavaType( UUID.class );
this.sessionUidColumn = new TemporaryTableSessionUidColumn(
this,
uuidType,
dialect.getTypeName(
uuidType.getJdbcType(),
typeConfiguration.getDdlTypeRegistry().getTypeName(
uuidType.getJdbcType().getDefaultSqlTypeCode(),
dialect.getSizeStrategy().resolveSize(
uuidType.getJdbcType(),
uuidType.getJavaTypeDescriptor(),
@ -136,7 +138,11 @@ public class TemporaryTable implements Exportable, Contributable {
temporaryTable,
column.getText( dialect ),
jdbcMapping,
column.getSqlType( dialect, runtimeModelCreationContext.getMetadata() ),
column.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
),
column.isNullable(),
true
)
@ -176,6 +182,7 @@ public class TemporaryTable implements Exportable, Contributable {
selectable.getText( dialect ),
selection.getJdbcMapping(),
column.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
),
@ -225,7 +232,11 @@ public class TemporaryTable implements Exportable, Contributable {
temporaryTable,
ENTITY_TABLE_IDENTITY_COLUMN,
jdbcMapping,
column.getSqlType( dialect, runtimeModelCreationContext.getMetadata() ) + " " +
column.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
) + " " +
dialect.getIdentityColumnSupport().getIdentityColumnString( column.getSqlTypeCode( runtimeModelCreationContext.getMetadata() ) ),
// Always report as nullable as the identity column string usually includes the not null constraint
true, //column.isNullable()
@ -253,7 +264,11 @@ public class TemporaryTable implements Exportable, Contributable {
temporaryTable,
column.getText( dialect ),
jdbcMapping,
column.getSqlType( dialect, runtimeModelCreationContext.getMetadata() ),
column.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
),
// We have to set the identity column after the root table insert
column.isNullable() || identityColumn || hasOptimizer,
!identityColumn && !hasOptimizer
@ -269,7 +284,11 @@ public class TemporaryTable implements Exportable, Contributable {
temporaryTable,
discriminator.getText( dialect ),
discriminatorMapping.getJdbcMapping(),
discriminator.getSqlType( dialect, runtimeModelCreationContext.getMetadata() ),
discriminator.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
),
// We have to set the identity column after the root table insert
discriminator.isNullable()
)
@ -294,6 +313,7 @@ public class TemporaryTable implements Exportable, Contributable {
selectable.getText( dialect ),
selection.getJdbcMapping(),
column.getSqlType(
runtimeModelCreationContext.getTypeConfiguration(),
dialect,
runtimeModelCreationContext.getMetadata()
),
@ -308,14 +328,12 @@ public class TemporaryTable implements Exportable, Contributable {
}
);
if ( hasOptimizer ) {
final TypeConfiguration typeConfiguration = runtimeModelCreationContext.getTypeConfiguration();
// We add a special row number column that we can use to identify and join rows
final BasicType<Integer> integerBasicType = entityDescriptor.getEntityPersister()
.getFactory()
.getTypeConfiguration()
.getBasicTypeForJavaType( Integer.class );
final BasicType<Integer> integerBasicType = typeConfiguration.getBasicTypeForJavaType( Integer.class );
final String rowNumberType;
if ( dialect.supportsWindowFunctions() ) {
rowNumberType = dialect.getTypeName(
rowNumberType = typeConfiguration.getDdlTypeRegistry().getTypeName(
integerBasicType.getJdbcType().getJdbcTypeCode(),
dialect.getSizeStrategy().resolveSize(
integerBasicType.getJdbcType(),
@ -327,7 +345,7 @@ public class TemporaryTable implements Exportable, Contributable {
);
}
else if ( dialect.getIdentityColumnSupport().supportsIdentityColumns() ) {
rowNumberType = dialect.getTypeName(
rowNumberType = typeConfiguration.getDdlTypeRegistry().getTypeName(
integerBasicType.getJdbcType().getJdbcTypeCode(),
dialect.getSizeStrategy().resolveSize(
integerBasicType.getJdbcType(),
@ -341,7 +359,7 @@ public class TemporaryTable implements Exportable, Contributable {
}
else {
LOG.multiTableInsertNotAvailable( entityBinding.getEntityName() );
rowNumberType = dialect.getTypeName(
rowNumberType = typeConfiguration.getDdlTypeRegistry().getTypeName(
integerBasicType.getJdbcType().getJdbcTypeCode(),
dialect.getSizeStrategy().resolveSize(
integerBasicType.getJdbcType(),

View File

@ -35,7 +35,9 @@ public class ExportableColumn extends Column {
table,
name,
type,
database.getDialect().getTypeName( type.getJdbcType().getDefaultSqlTypeCode() )
database.getTypeConfiguration()
.getDdlTypeRegistry()
.getTypeName( type.getJdbcType().getDefaultSqlTypeCode(), database.getDialect() )
);
}

View File

@ -688,7 +688,9 @@ public class TableGenerator implements PersistentIdentifierGenerator {
table,
segmentColumnName,
basicTypeRegistry.resolve( StandardBasicTypes.STRING ),
dialect.getTypeName( Types.VARCHAR, Size.length(segmentValueLength) )
database.getTypeConfiguration()
.getDdlTypeRegistry()
.getTypeName( Types.VARCHAR, Size.length( segmentValueLength ) )
);
segmentColumn.setNullable( false );
table.addColumn( segmentColumn );

View File

@ -79,6 +79,7 @@ public class FilterHelper {
filter.getCondition(),
FilterImpl.MARKER,
factory.getJdbcServices().getDialect(),
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
filterConditions[filterCount] = safeInterning( autoAliasedCondition );

View File

@ -22,6 +22,7 @@ import org.hibernate.sql.Template;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.internal.util.StringHelper.safeInterning;
@ -240,10 +241,10 @@ public class Column implements Selectable, Serializable, Cloneable {
sqlTypeCode = typeCode;
}
public String getSqlType(Dialect dialect, Mapping mapping) throws HibernateException {
public String getSqlType(TypeConfiguration typeConfiguration, Dialect dialect, Mapping mapping) throws HibernateException {
if ( sqlType == null ) {
try {
sqlType = dialect.getTypeName( getSqlTypeCode( mapping ), getColumnSize( dialect, mapping ) );
sqlType = typeConfiguration.getDdlTypeRegistry().getTypeName( getSqlTypeCode( mapping ), getColumnSize( dialect, mapping ) );
}
catch (HibernateException cause) {
throw new HibernateException(
@ -365,7 +366,10 @@ public class Column implements Selectable, Serializable, Cloneable {
}
@Override
public String getTemplate(Dialect dialect, SqmFunctionRegistry functionRegistry) {
public String getTemplate(
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
return safeInterning(
hasCustomRead()
// see note in renderTransformerReadFragment wrt access to SessionFactory

View File

@ -14,6 +14,7 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.loader.internal.AliasConstantsHelper;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.sql.Template;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.internal.util.StringHelper.safeInterning;
@ -38,8 +39,11 @@ public class Formula implements Selectable, Serializable {
}
@Override
public String getTemplate(Dialect dialect, SqmFunctionRegistry functionRegistry) {
String template = Template.renderWhereStringTemplate(formula, dialect, functionRegistry);
public String getTemplate(
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
String template = Template.renderWhereStringTemplate( formula, dialect, typeConfiguration, functionRegistry );
return safeInterning( StringHelper.replace( template, "{alias}", Template.TEMPLATE ) );
}

View File

@ -8,6 +8,7 @@ package org.hibernate.mapping;
import org.hibernate.dialect.Dialect;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Models the commonality between a column and a formula (computed value).
@ -60,9 +61,8 @@ public interface Selectable {
@Deprecated(since = "6.0")
String getAlias(Dialect dialect, Table table);
/**
* @deprecated use {@link #getCustomWriteExpression()} instead
*/
@Deprecated(since = "6.0")
String getTemplate(Dialect dialect, SqmFunctionRegistry functionRegistry);
String getTemplate(
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry);
}

View File

@ -441,7 +441,11 @@ public class Table implements RelationalModel, Serializable, ContributableDataba
.append( ' ' )
.append( column.getQuotedName( dialect ) );
String columnType = column.getSqlType(dialect, metadata);
String columnType = column.getSqlType(
metadata.getDatabase().getTypeConfiguration(),
dialect,
metadata
);
if ( column.getGeneratedAs()==null || dialect.hasDataTypeBeforeGeneratedAs() ) {
alter.append( ' ' ).append(columnType);
}

View File

@ -166,7 +166,11 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
final String columnExpression;
if ( rootTableKeyColumnNames == null ) {
if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, creationProcess.getSqmFunctionRegistry() );
columnExpression = selectable.getTemplate(
dialect,
creationProcess.getCreationContext().getTypeConfiguration(),
creationProcess.getSqmFunctionRegistry()
);
}
else {
columnExpression = selectable.getText( dialect );

View File

@ -312,7 +312,11 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
final String columnExpression;
if ( rootTableKeyColumnNames == null ) {
if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, creationProcess.getSqmFunctionRegistry() );
columnExpression = selectable.getTemplate(
dialect,
creationProcess.getCreationContext().getTypeConfiguration(),
creationProcess.getSqmFunctionRegistry()
);
}
else {
columnExpression = selectable.getText( dialect );

View File

@ -305,6 +305,7 @@ public class EntityCollectionPart
fkKeyTableName,
fkBootDescriptorSource.getSelectables().get(0),
basicFkTargetPart.getJdbcMapping(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);

View File

@ -593,6 +593,7 @@ public class MappingModelCreationHelper {
tableExpression,
index.getSelectables().get(0),
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -644,6 +645,7 @@ public class MappingModelCreationHelper {
tableExpression,
index.getSelectables().get(0),
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -873,6 +875,7 @@ public class MappingModelCreationHelper {
tableExpression,
bootValueMappingKey.getSelectables().get(0),
(JdbcMapping) keyType,
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1044,6 +1047,7 @@ public class MappingModelCreationHelper {
tableExpression,
columnIterator.next(),
simpleFkTarget.getJdbcMapping(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1054,6 +1058,7 @@ public class MappingModelCreationHelper {
tableExpression,
table.getColumn( 0 ),
simpleFkTarget.getJdbcMapping(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1168,6 +1173,7 @@ public class MappingModelCreationHelper {
collectionBootValueMapping.getKey(),
getPropertyOrder( bootValueMapping, creationProcess ),
creationProcess.getCreationContext().getSessionFactory(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1189,6 +1195,7 @@ public class MappingModelCreationHelper {
bootValueMapping,
getPropertyOrder( bootValueMapping, creationProcess ),
creationProcess.getCreationContext().getSessionFactory(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1335,6 +1342,7 @@ public class MappingModelCreationHelper {
tableExpression,
basicValue.getSelectables().get(0),
basicValue.resolve().getJdbcMapping(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
@ -1419,6 +1427,7 @@ public class MappingModelCreationHelper {
tableExpression,
basicElement.getSelectables().get(0),
basicElement.resolve().getJdbcMapping(),
creationProcess.getCreationContext().getTypeConfiguration(),
dialect,
creationProcess.getSqmFunctionRegistry()
);

View File

@ -12,6 +12,7 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Christian Beikov
@ -48,6 +49,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
final String containingTableExpression,
final Selectable selectable,
final JdbcMapping jdbcMapping,
final TypeConfiguration typeConfiguration,
final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) {
final String columnExpression;
@ -56,7 +58,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select
final Integer precision;
final Integer scale;
if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, sqmFunctionRegistry );
columnExpression = selectable.getTemplate( dialect, typeConfiguration, sqmFunctionRegistry );
columnDefinition = null;
length = null;
precision = null;

View File

@ -23,6 +23,7 @@ import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Christian Beikov
@ -59,6 +60,7 @@ public class SelectableMappingsImpl implements SelectableMappings {
Value value,
int[] propertyOrder,
Mapping mapping,
TypeConfiguration typeConfiguration,
Dialect dialect,
SqmFunctionRegistry sqmFunctionRegistry) {
final List<JdbcMapping> jdbcMappings = new ArrayList<>();
@ -72,6 +74,7 @@ public class SelectableMappingsImpl implements SelectableMappings {
containingTableExpression,
selectables.get( i ),
jdbcMappings.get( propertyOrder[i] ),
typeConfiguration,
dialect,
sqmFunctionRegistry
);

View File

@ -329,6 +329,7 @@ public abstract class AbstractCollectionPersister
sqlWhereStringTemplate = Template.renderWhereStringTemplate(
sqlWhereString,
dialect,
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
}
@ -399,7 +400,11 @@ public abstract class AbstractCollectionPersister
elementColumnAliases[j] = selectable.getAlias( dialect, table );
if ( selectable.isFormula() ) {
Formula form = (Formula) selectable;
elementFormulaTemplates[j] = form.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() );
elementFormulaTemplates[j] = form.getTemplate(
dialect,
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
elementFormulas[j] = form.getFormula();
}
else {
@ -407,7 +412,11 @@ public abstract class AbstractCollectionPersister
elementColumnNames[j] = col.getQuotedName( dialect );
elementColumnWriters[j] = col.getWriteExpr();
elementColumnReaders[j] = col.getReadExpr( dialect );
elementColumnReaderTemplates[j] = col.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() );
elementColumnReaderTemplates[j] = col.getTemplate(
dialect,
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
elementColumnIsGettable[j] = true;
if ( elementType.isComponentType() ) {
// Implements desired behavior specifically for @ElementCollection mappings.
@ -456,7 +465,11 @@ public abstract class AbstractCollectionPersister
indexColumnAliases[i] = s.getAlias( dialect );
if ( s.isFormula() ) {
Formula indexForm = (Formula) s;
indexFormulaTemplates[i] = indexForm.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() );
indexFormulaTemplates[i] = indexForm.getTemplate(
dialect,
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
indexFormulas[i] = indexForm.getFormula();
hasFormula = true;
}
@ -647,6 +660,7 @@ public abstract class AbstractCollectionPersister
manyToManyWhereTemplate = Template.renderWhereStringTemplate(
manyToManyWhereString,
factory.getJdbcServices().getDialect(),
factory.getTypeConfiguration(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
}

View File

@ -777,7 +777,11 @@ public abstract class AbstractEntityPersister
Column column = columns.get(i);
rootTableKeyColumnNames[i] = column.getQuotedName( dialect );
rootTableKeyColumnReaders[i] = column.getReadExpr( dialect );
rootTableKeyColumnReaderTemplates[i] = column.getTemplate( dialect, functionRegistry );
rootTableKeyColumnReaderTemplates[i] = column.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
identifierAliases[i] = column.getAlias( dialect, bootDescriptor.getRootTable() );
}
@ -806,6 +810,7 @@ public abstract class AbstractEntityPersister
sqlWhereStringTemplate = Template.renderWhereStringTemplate(
"(" + bootDescriptor.getWhere() + ")",
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
}
@ -853,7 +858,11 @@ public abstract class AbstractEntityPersister
foundFormula = true;
Formula formula = (Formula) selectable;
formula.setFormula( substituteBrackets( formula.getFormula() ) );
formulaTemplates[k] = selectable.getTemplate( dialect, functionRegistry );
formulaTemplates[k] = selectable.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
}
else {
Column column = (Column) selectable;
@ -961,7 +970,11 @@ public abstract class AbstractEntityPersister
for ( int i = 0; i < selectables.size(); i++ ) {
Selectable selectable = selectables.get(i);
if ( selectable.isFormula() ) {
String template = selectable.getTemplate( dialect, functionRegistry );
String template = selectable.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
// formnos[l] = formulaTemplates.size();
// colnos[l] = -1;
// formulaTemplates.add( template );
@ -982,7 +995,11 @@ public abstract class AbstractEntityPersister
columnSelectables.add( prop.isSelectable() );
readers[i] = column.getReadExpr( dialect );
readerTemplates[i] = column.getTemplate( dialect, functionRegistry );
readerTemplates[i] = column.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
// columnReaderTemplates.add( readerTemplate );
}
}
@ -6196,7 +6213,11 @@ public abstract class AbstractEntityPersister
assert attrColumnExpression.equals( selectable.getText(sessionFactory.getJdbcServices().getDialect()) );
customReadExpr = selectable.getTemplate( dialect, sessionFactory.getQueryEngine().getSqmFunctionRegistry() );
customReadExpr = selectable.getTemplate(
dialect,
sessionFactory.getTypeConfiguration(),
sessionFactory.getQueryEngine().getSqmFunctionRegistry()
);
customWriteExpr = selectable.getCustomWriteExpression();
Column column = bootValue.getColumns().get( 0 );
columnDefinition = column.getSqlType();

View File

@ -250,7 +250,11 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
Column column = columns.get(k);
keyCols[k] = column.getQuotedName( dialect );
keyColReaders[k] = column.getReadExpr( dialect );
keyColReaderTemplates[k] = column.getTemplate( dialect, sqmFunctionRegistry );
keyColReaderTemplates[k] = column.getTemplate(
dialect,
factory.getTypeConfiguration(),
sqmFunctionRegistry
);
}
keyColumns.add( keyCols );
keyColumnReaders.add( keyColReaders );
@ -285,7 +289,11 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
Column column = columns.get(k);
keyCols[k] = column.getQuotedName( dialect );
keyColReaders[k] = column.getReadExpr( dialect );
keyColReaderTemplates[k] = column.getTemplate( dialect, sqmFunctionRegistry );
keyColReaderTemplates[k] = column.getTemplate(
dialect,
factory.getTypeConfiguration(),
sqmFunctionRegistry
);
}
keyColumns.add( keyCols );
keyColumnReaders.add( keyColReaders );

View File

@ -25,7 +25,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Column;
@ -304,7 +303,11 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
if ( discriminator.hasFormula() ) {
Formula formula = (Formula) selectable;
// discriminatorFormula = formula.getFormula();
discriminatorFormulaTemplate = formula.getTemplate( dialect, functionRegistry );
discriminatorFormulaTemplate = formula.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
discriminatorColumnName = null;
discriminatorColumnReaders = null;
discriminatorColumnReaderTemplate = null;
@ -314,7 +317,11 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Column column = (Column) selectable;
discriminatorColumnName = column.getQuotedName( dialect );
discriminatorColumnReaders = column.getReadExpr( dialect );
discriminatorColumnReaderTemplate = column.getTemplate( dialect, functionRegistry );
discriminatorColumnReaderTemplate = column.getTemplate(
dialect,
factory.getTypeConfiguration(),
functionRegistry
);
discriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() );
// discriminatorFormula = null;
discriminatorFormulaTemplate = null;

View File

@ -450,7 +450,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
for ( Column col : columns ) {
if ( !table.containsColumn(col) ) {
int sqlType = col.getSqlTypeCode( mapping );
buf.append( dialect.getSelectClauseNullString(sqlType) )
buf.append( dialect.getSelectClauseNullString( sqlType, getFactory().getTypeConfiguration() ) )
.append(" as ");
}
buf.append(col.getQuotedName(dialect));
@ -528,7 +528,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
selectableMapping = selectableMappings.values().iterator().next();
final int sqlType = selectableMapping.getJdbcMapping().getJdbcType()
.getDefaultSqlTypeCode();
buf.append( dialect.getSelectClauseNullString( sqlType ) )
buf.append( dialect.getSelectClauseNullString( sqlType, getFactory().getTypeConfiguration() ) )
.append( " as " );
}
buf.append(

View File

@ -138,7 +138,10 @@ public class SelfRenderingFunctionSqlAstExpression
}
@Override
public String getTemplate(Dialect dialect, SqmFunctionRegistry functionRegistry) {
public String getTemplate(
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
return null;
}

View File

@ -18,6 +18,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Parses SQL fragments specified in mapping documents
@ -94,8 +95,12 @@ public final class Template {
return fragment;
}
public static String renderWhereStringTemplate(String sqlWhereString, Dialect dialect, SqmFunctionRegistry functionRegistry) {
return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, functionRegistry);
public static String renderWhereStringTemplate(
String sqlWhereString,
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, typeConfiguration, functionRegistry);
}
/**
@ -109,7 +114,12 @@ public final class Template {
* @param functionRegistry The registry of all sql functions
* @return The rendered sql fragment
*/
public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SqmFunctionRegistry functionRegistry ) {
public static String renderWhereStringTemplate(
String sqlWhereString,
String placeholder,
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
// IMPL NOTE : The basic process here is to tokenize the incoming string and to iterate over each token
// in turn. As we process each token, we set a series of flags used to indicate the type of context in
@ -182,6 +192,7 @@ public final class Template {
extractUntil( tokens, ")" ),
placeholder,
dialect,
typeConfiguration,
functionRegistry
);
result.append( "extract(" ).append( field ).append( " from " ).append( source ).append( ')' );
@ -273,7 +284,7 @@ public final class Template {
}
else {
result.append(
renderWhereStringTemplate( trimOperands.trimSpec, placeholder, dialect, functionRegistry )
renderWhereStringTemplate( trimOperands.trimSpec, placeholder, dialect, typeConfiguration, functionRegistry )
);
}
result.append( ' ' );
@ -286,7 +297,7 @@ public final class Template {
result.append( "from " );
}
result.append( renderWhereStringTemplate( trimOperands.trimSource, placeholder, dialect, functionRegistry ) )
result.append( renderWhereStringTemplate( trimOperands.trimSource, placeholder, dialect, typeConfiguration, functionRegistry ) )
.append( ')' );
hasMore = tokens.hasMoreTokens();
@ -316,7 +327,7 @@ public final class Template {
result.append(token);
}
else if ( isIdentifier(token)
&& !isFunctionOrKeyword(lcToken, nextToken, dialect , functionRegistry) ) {
&& !isFunctionOrKeyword(lcToken, nextToken, dialect, typeConfiguration, functionRegistry) ) {
result.append(placeholder)
.append('.')
.append( dialect.quote(token) );
@ -650,17 +661,18 @@ public final class Template {
String lcToken,
String nextToken,
Dialect dialect,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
return "(".equals( nextToken ) ||
KEYWORDS.contains( lcToken ) ||
isType( lcToken, dialect ) ||
isType( lcToken, typeConfiguration ) ||
isFunction( lcToken, nextToken, functionRegistry ) ||
dialect.getKeywords().contains( lcToken ) ||
FUNCTION_KEYWORDS.contains( lcToken );
}
private static boolean isType(String lcToken, Dialect dialect) {
return dialect.isTypeNameRegistered( lcToken );
private static boolean isType(String lcToken, TypeConfiguration typeConfiguration) {
return typeConfiguration.getDdlTypeRegistry().isTypeNameRegistered( lcToken );
}
private static boolean isFunction(String lcToken, String nextToken, SqmFunctionRegistry functionRegistry) {

View File

@ -4256,13 +4256,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( castTarget.getSqlType() );
}
else {
final SqlExpressible expressionType = (SqlExpressible) castTarget.getExpressionType();
appendSql(
getDialect().getCastTypeName(
(SqlExpressible) castTarget.getExpressionType(),
castTarget.getLength(),
castTarget.getPrecision(),
castTarget.getScale()
)
sessionFactory.getTypeConfiguration().getDdlTypeRegistry()
.getDescriptor( expressionType.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode() )
.getCastTypeName(
expressionType,
castTarget.getLength(),
castTarget.getPrecision(),
castTarget.getScale()
)
);
}
}

View File

@ -159,7 +159,7 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
ExecutionOptions options,
Dialect dialect) {
boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode( metadata ), columnInformation.getTypeCode() )
|| column.getSqlType( dialect, metadata ).toLowerCase(Locale.ROOT)
|| column.getSqlType( metadata.getDatabase().getTypeConfiguration(), dialect, metadata ).toLowerCase(Locale.ROOT)
.startsWith( columnInformation.getTypeName().toLowerCase(Locale.ROOT) );
if ( !typesMatch ) {
throw new SchemaManagementException(

View File

@ -85,14 +85,20 @@ public class StandardTableExporter implements Exporter<Table> {
if ( isPrimaryKeyIdentity && colName.equals( pkColName ) ) {
// to support dialects that have their own identity data type
if ( dialect.getIdentityColumnSupport().hasDataTypeInIdentityColumn() ) {
buf.append( ' ' ).append( col.getSqlType( dialect, metadata ) );
buf.append( ' ' ).append(
col.getSqlType( metadata.getDatabase().getTypeConfiguration(), dialect, metadata )
);
}
String identityColumnString = dialect.getIdentityColumnSupport()
.getIdentityColumnString( col.getSqlTypeCode(metadata) );
buf.append( ' ' ).append( identityColumnString );
}
else {
final String columnType = col.getSqlType( dialect, metadata );
final String columnType = col.getSqlType(
metadata.getDatabase().getTypeConfiguration(),
dialect,
metadata
);
if ( col.getGeneratedAs()==null || dialect.hasDataTypeBeforeGeneratedAs() ) {
buf.append( ' ' ).append( columnType );
}

View File

@ -9,12 +9,14 @@ package org.hibernate.type.descriptor.jdbc;
import java.io.Serializable;
import java.sql.Types;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.query.sqm.CastType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -56,7 +58,7 @@ public interface JdbcType extends Serializable {
* A {@linkplain SqlTypes JDBC type code} that identifies the SQL column type to
* be used for schema generation.
* <p>
* This value is passed to {@link org.hibernate.dialect.Dialect#getTypeName(int)}
* This value is passed to {@link DdlTypeRegistry#getTypeName(int, Size)}
* to obtain the SQL column type.
*
* @return a JDBC type code
@ -108,7 +110,11 @@ public interface JdbcType extends Serializable {
<X> ValueExtractor<X> getExtractor(JavaType<X> javaType);
default boolean isInteger() {
switch ( getJdbcTypeCode() ) {
return isInteger( getJdbcTypeCode() );
}
static boolean isInteger(int typeCode) {
switch ( typeCode ) {
case Types.BIT:
case Types.TINYINT:
case Types.SMALLINT:
@ -120,7 +126,11 @@ public interface JdbcType extends Serializable {
}
default boolean isFloat() {
switch ( getJdbcTypeCode() ) {
return isFloat( getJdbcTypeCode() );
}
static boolean isFloat(int typeCode) {
switch ( typeCode ) {
case Types.FLOAT:
case Types.REAL:
case Types.DOUBLE:
@ -130,7 +140,11 @@ public interface JdbcType extends Serializable {
}
default boolean isDecimal() {
switch ( getJdbcTypeCode() ) {
return isDecimal( getJdbcTypeCode() );
}
static boolean isDecimal(int typeCode) {
switch ( typeCode ) {
case Types.DECIMAL:
case Types.NUMERIC:
return true;
@ -139,7 +153,11 @@ public interface JdbcType extends Serializable {
}
default boolean isNumber() {
switch ( getJdbcTypeCode() ) {
return isNumber( getJdbcTypeCode() );
}
static boolean isNumber(int typeCode) {
switch ( typeCode ) {
case Types.BIT:
case Types.TINYINT:
case Types.SMALLINT:
@ -156,7 +174,11 @@ public interface JdbcType extends Serializable {
}
default boolean isBinary() {
switch ( getJdbcTypeCode() ) {
return isBinary( getJdbcTypeCode() );
}
static boolean isBinary(int typeCode) {
switch ( typeCode ) {
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
@ -167,7 +189,11 @@ public interface JdbcType extends Serializable {
}
default boolean isString() {
switch ( getJdbcTypeCode() ) {
return isString( getJdbcTypeCode() );
}
static boolean isString(int typeCode) {
switch ( typeCode ) {
case Types.CHAR:
case Types.NCHAR:
case Types.VARCHAR:
@ -182,7 +208,11 @@ public interface JdbcType extends Serializable {
}
default boolean isTemporal() {
switch ( getJdbcTypeCode() ) {
return isTemporal( getDefaultSqlTypeCode() );
}
static boolean isTemporal(int typeCode) {
switch ( typeCode ) {
case Types.DATE:
case Types.TIME:
case Types.TIMESTAMP:
@ -193,7 +223,11 @@ public interface JdbcType extends Serializable {
}
default boolean isInterval() {
switch ( getDefaultSqlTypeCode() ) {
return isInterval( getDefaultSqlTypeCode() );
}
static boolean isInterval(int typeCode) {
switch ( typeCode ) {
case SqlTypes.INTERVAL_SECOND:
return true;
}
@ -201,7 +235,11 @@ public interface JdbcType extends Serializable {
}
default CastType getCastType() {
switch ( getJdbcTypeCode() ) {
return getCastType( getJdbcTypeCode() );
}
static CastType getCastType(int typeCode) {
switch ( typeCode ) {
case Types.INTEGER:
case Types.TINYINT:
case Types.SMALLINT:

View File

@ -0,0 +1,63 @@
/*
* 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;
import java.io.Serializable;
import java.sql.Types;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* Descriptor for a DDL type.
*
* @author Christian Beikov
*/
public interface DdlType extends Serializable {
/**
* The {@linkplain SqlTypes SQL type code} of the descriptor.
*
* @return a SQL type code
*/
int getSqlTypeCode();
String getRawTypeName();
String getTypeNamePattern();
default String getTypeName(Size size) {
return getTypeName( size.getLength(), size.getPrecision(), size.getScale() );
}
String getTypeName(Long size, Integer precision, Integer scale);
String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType);
/**
* Get the name of the database type appropriate for casting operations
* (via the CAST() SQL function) for the given {@link SqlExpressible}
* SQL type.
*
* @return The database type name
*/
default String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
return getCastTypeName(
type.getJdbcMapping().getJdbcType(),
type.getJdbcMapping().getJavaTypeDescriptor(),
length,
precision,
scale
);
}
String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType, Long length, Integer precision, Integer scale);
}

View File

@ -0,0 +1,34 @@
/*
* 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.type.SqlTypes;
import static java.lang.Math.log;
public class BinaryFloatDdlType extends DdlTypeImpl {
//needed for converting precision from decimal to binary digits
private static final double LOG_BASE2OF10 = log(10)/log(2);
public BinaryFloatDdlType(Dialect dialect) {
this( "float($p)", dialect );
}
public BinaryFloatDdlType(String typeNamePattern, Dialect dialect) {
super( SqlTypes.FLOAT, typeNamePattern, dialect );
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
if ( precision != null ) {
return super.getTypeName( size, (int) ( precision / LOG_BASE2OF10 ), scale );
}
return super.getTypeName( size, precision, scale );
}
}

View File

@ -0,0 +1,109 @@
/*
* 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 java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.hibernate.dialect.Dialect;
/**
* Descriptor for a SQL type.
*
* @author Christian Beikov
*/
public class CapacityDependentDdlType extends DdlTypeImpl {
private final TypeEntry[] typeEntries;
private CapacityDependentDdlType(Builder builder) {
super(
builder.sqlTypeCode,
builder.typeNamePattern,
builder.castTypeNamePattern,
builder.dialect
);
builder.typeEntries.sort( Comparator.naturalOrder() );
this.typeEntries = builder.typeEntries.toArray(new TypeEntry[0]);
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
if ( size != null && size > 0 ) {
for ( TypeEntry typeEntry : typeEntries ) {
if ( size <= typeEntry.capacity ) {
return replace( typeEntry.typeNamePattern, size, precision, scale );
}
}
}
else if ( precision != null && precision > 0 ) {
for ( TypeEntry typeEntry : typeEntries ) {
if ( precision <= typeEntry.capacity ) {
return replace( typeEntry.typeNamePattern, size, precision, scale );
}
}
}
return super.getTypeName( size, precision, scale );
}
public static Builder builder(int sqlTypeCode, String typeNamePattern, Dialect dialect) {
return builder( sqlTypeCode, typeNamePattern, typeNamePattern, dialect );
}
public static Builder builder(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern,
Dialect dialect) {
return new Builder( sqlTypeCode, typeNamePattern, castTypeNamePattern, dialect );
}
public static class Builder {
private final int sqlTypeCode;
private final String typeNamePattern;
private final String castTypeNamePattern;
private final Dialect dialect;
private final List<TypeEntry> typeEntries;
private Builder(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern,
Dialect dialect) {
this.sqlTypeCode = sqlTypeCode;
this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern;
this.dialect = dialect;
this.typeEntries = new ArrayList<>();
}
public Builder withTypeCapacity(long capacity, String typeNamePattern) {
typeEntries.add( new TypeEntry( capacity, typeNamePattern ) );
return this;
}
public CapacityDependentDdlType build() {
return new CapacityDependentDdlType( this );
}
}
private static class TypeEntry implements Comparable<TypeEntry> {
private final long capacity;
private final String typeNamePattern;
public TypeEntry(long capacity, String typeNamePattern) {
this.capacity = capacity;
this.typeNamePattern = typeNamePattern;
}
@Override
public int compareTo(TypeEntry o) {
return Long.compare( capacity, o.capacity );
}
}
}

View File

@ -0,0 +1,130 @@
/*
* 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.internal.util.StringHelper;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.DdlType;
/**
* Descriptor for a SQL type.
*
* @author Christian Beikov
*/
public class DdlTypeImpl implements DdlType {
private final int sqlTypeCode;
private final String typeNamePattern;
private final String castTypeNamePattern;
private final boolean castTypeNameIsStatic;
private final Dialect dialect;
public DdlTypeImpl(int sqlTypeCode, String typeNamePattern, Dialect dialect) {
this( sqlTypeCode, typeNamePattern, typeNamePattern, dialect );
}
public DdlTypeImpl(
int sqlTypeCode,
String typeNamePattern,
String castTypeNamePattern,
Dialect dialect) {
this.sqlTypeCode = sqlTypeCode;
this.typeNamePattern = typeNamePattern;
this.castTypeNamePattern = castTypeNamePattern;
this.castTypeNameIsStatic = !castTypeNamePattern.contains( "$s" )
&& !castTypeNamePattern.contains( "$l" )
&& !castTypeNamePattern.contains( "$p" );
this.dialect = dialect;
}
@Override
public int getSqlTypeCode() {
return sqlTypeCode;
}
@Override
public String getRawTypeName() {
//trim off the length/precision/scale
final int paren = typeNamePattern.indexOf( '(' );
return paren > 0 ? typeNamePattern.substring( 0, paren ) : typeNamePattern;
}
@Override
public String getTypeNamePattern() {
return typeNamePattern;
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
return replace( typeNamePattern, size, precision, scale );
}
@Override
public String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType, Long length, Integer precision, Integer scale) {
if ( length == null && precision == null ) {
return getCastTypeName( jdbcType, javaType );
}
else {
//use the given length/precision/scale
if ( precision != null && scale == null ) {
//needed for cast(x as BigInteger(p))
scale = javaType.getDefaultSqlScale( dialect, jdbcType );
}
}
return getTypeName( length, precision, scale );
}
@Override
public String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType) {
if ( castTypeNameIsStatic ) {
return castTypeNamePattern;
}
Long length = null;
Integer precision = null;
Integer scale = null;
switch ( jdbcType.getDefaultSqlTypeCode() ) {
case SqlTypes.VARCHAR:
length = (long) dialect.getMaxVarcharLength();
break;
case SqlTypes.NVARCHAR:
length = (long) dialect.getMaxNVarcharLength();
break;
case SqlTypes.VARBINARY:
length = (long) dialect.getMaxVarbinaryLength();
break;
}
final Size size = dialect.getSizeStrategy().resolveSize(
jdbcType,
javaType,
precision,
scale,
length
);
return replace( castTypeNamePattern, size.getLength(), size.getPrecision(), size.getScale() );
}
/**
* Fill in the placemarkers with the given length, precision, and scale.
*/
public static String replace(String type, Long size, Integer precision, Integer scale) {
if ( scale != null ) {
type = StringHelper.replaceOnce( type, "$s", scale.toString() );
}
if ( size != null ) {
type = StringHelper.replaceOnce( type, "$l", size.toString() );
}
if ( precision != null ) {
type = StringHelper.replaceOnce( type, "$p", precision.toString() );
}
return type;
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.type.SqlTypes;
public class Scale6IntervalSecondDdlType extends DdlTypeImpl {
public Scale6IntervalSecondDdlType(Dialect dialect) {
this( "interval second($s)", dialect );
}
public Scale6IntervalSecondDdlType(String typeNamePattern, Dialect dialect) {
super( SqlTypes.INTERVAL_SECOND, typeNamePattern, dialect );
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
// The maximum scale for `interval second` is 6 unfortunately so we have to use numeric by default
if ( scale == null || scale > 6 ) {
return DdlTypeImpl.replace( "numeric($p,$s)", size, precision, scale );
}
return super.getTypeName( size, precision, scale );
}
}

View File

@ -0,0 +1,134 @@
/*
* 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.spi;
import java.io.Serializable;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.sql.DdlType;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
/**
* Basically a map from SQL type code (int) -> {@link DdlType}
*
* @author Christian Beikov
*
* @since 6.0
*/
public class DdlTypeRegistry implements Serializable {
private static final Logger log = Logger.getLogger( DdlTypeRegistry.class );
private final Map<Integer, DdlType> ddlTypes = new HashMap<>();
public DdlTypeRegistry(TypeConfiguration typeConfiguration) {
// this.typeConfiguration = typeConfiguration;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// baseline descriptors
public void addDescriptor(DdlType ddlType) {
final DdlType previous = ddlTypes.put( ddlType.getSqlTypeCode(), ddlType );
if ( previous != null && previous != ddlType ) {
log.debugf( "addDescriptor(%s) replaced previous registration(%s)", ddlType, previous );
}
}
public void addDescriptor(int sqlTypeCode, DdlType ddlType) {
final DdlType previous = ddlTypes.put( sqlTypeCode, ddlType );
if ( previous != null && previous != ddlType ) {
log.debugf( "addDescriptor(%d, %s) replaced previous registration(%s)", sqlTypeCode, ddlType, previous );
}
}
public void addDescriptorIfAbsent(DdlType jdbcType) {
ddlTypes.putIfAbsent( jdbcType.getSqlTypeCode(), jdbcType );
}
public void addDescriptorIfAbsent(int sqlTypeCode, DdlType jdbcType) {
ddlTypes.putIfAbsent( sqlTypeCode, jdbcType );
}
public DdlType getDescriptor(int sqlTypeCode) {
return ddlTypes.get( sqlTypeCode );
}
public String getTypeName(int typeCode, Dialect dialect) {
// explicitly enforce dialect's default precisions
switch ( typeCode ) {
case Types.DECIMAL:
case Types.NUMERIC:
return getTypeName( typeCode, Size.precision( dialect.getDefaultDecimalPrecision() ) );
case Types.FLOAT:
case Types.REAL:
return getTypeName( typeCode, Size.precision( dialect.getFloatPrecision() ) );
case Types.DOUBLE:
return getTypeName( typeCode, Size.precision( dialect.getDoublePrecision() ) );
case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
return getTypeName( typeCode, Size.precision( dialect.getDefaultTimestampPrecision() ) );
default:
return getTypeName( typeCode, Size.nil() );
}
}
public String getTypeName(int typeCode, Size size) {
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 given length, precision, and scale.
*
* @param typeCode the JDBC type code
* @param size the SQL length, if any
* @param precision the SQL precision, if any
* @param scale the SQL scale, if any
*
* @return the associated name with smallest capacity >= size, if available and
* the default type name otherwise
*/
public String getTypeName(int typeCode, Long size, Integer precision, Integer scale) {
final DdlType descriptor = getDescriptor( typeCode );
if ( descriptor == null ) {
throw new HibernateException(
String.format(
"No type mapping for java.sql.Types code: %s",
typeCode
)
);
}
return descriptor.getTypeName( size, precision, scale );
}
/**
* Whether or not the given type name has been registered for this dialect (including both hibernate type names and
* custom-registered type names).
*
* @param typeName the type name.
*
* @return true if the given string has been registered either as a hibernate type or as a custom-registered one
*/
public boolean isTypeNameRegistered(final String typeName) {
for ( DdlType value : ddlTypes.values() ) {
if ( value.getRawTypeName().equals( typeName ) ) {
return true;
}
}
return false;
}
}

View File

@ -63,6 +63,7 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.hibernate.type.internal.BasicTypeImpl;
import jakarta.persistence.TemporalType;
@ -99,6 +100,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
// things available during both boot and runtime lifecycle phases
private final transient JavaTypeRegistry javaTypeRegistry;
private final transient JdbcTypeRegistry jdbcTypeRegistry;
private final transient DdlTypeRegistry ddlTypeRegistry;
private final transient BasicTypeRegistry basicTypeRegistry;
private final transient Map<Integer, Set<String>> jdbcToHibernateTypeContributionMap = new HashMap<>();
@ -108,7 +110,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
this.javaTypeRegistry = new JavaTypeRegistry( this );
this.jdbcTypeRegistry = new JdbcTypeRegistry( this );
this.ddlTypeRegistry = new DdlTypeRegistry( this );
this.basicTypeRegistry = new BasicTypeRegistry( this );
StandardBasicTypes.prime( this );
}
@ -121,7 +123,6 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
return basicTypeRegistry;
}
public JavaTypeRegistry getJavaTypeRegistry() {
return javaTypeRegistry;
}
@ -130,6 +131,10 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
return jdbcTypeRegistry;
}
public DdlTypeRegistry getDdlTypeRegistry() {
return ddlTypeRegistry;
}
public JdbcTypeIndicators getCurrentBaseSqlTypeIndicators() {
return scope.getCurrentBaseSqlTypeIndicators();
}

View File

@ -11,7 +11,9 @@ import java.sql.Types;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.query.spi.Limit;
import org.hibernate.type.spi.TypeConfiguration;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
@ -28,11 +30,18 @@ import static org.junit.Assert.assertTrue;
public class DB2DialectTestCase extends BaseUnitTestCase {
private final DB2Dialect dialect = new DB2Dialect();
private TypeConfiguration typeConfiguration;
@Before
public void setup() {
typeConfiguration = new TypeConfiguration();
dialect.contributeTypes( () -> typeConfiguration, null );
}
@Test
@TestForIssue(jiraKey = "HHH-6866")
public void testGetDefaultBinaryTypeName() {
String actual = dialect.getTypeName( Types.BINARY );
String actual = typeConfiguration.getDdlTypeRegistry().getTypeName( Types.BINARY, dialect );
assertEquals(
"The default column length is 255, but char length on DB2 is limited to 254",
"varchar($l) for bit data",
@ -44,7 +53,7 @@ public class DB2DialectTestCase extends BaseUnitTestCase {
@TestForIssue(jiraKey = "HHH-6866")
public void testGetExplicitBinaryTypeName() {
// lower bound
String actual = dialect.getTypeName( Types.BINARY, Size.length(1) );
String actual = typeConfiguration.getDdlTypeRegistry().getTypeName( Types.BINARY, Size.length( 1) );
assertEquals(
"Wrong binary type",
"char(1) for bit data",
@ -52,7 +61,7 @@ public class DB2DialectTestCase extends BaseUnitTestCase {
);
// upper bound
actual = dialect.getTypeName( Types.BINARY, Size.length(254) );
actual = typeConfiguration.getDdlTypeRegistry().getTypeName( Types.BINARY, Size.length( 254) );
assertEquals(
"Wrong binary type. 254 is the max length in DB2",
"char(254) for bit data",
@ -60,7 +69,7 @@ public class DB2DialectTestCase extends BaseUnitTestCase {
);
// exceeding upper bound
actual = dialect.getTypeName( Types.BINARY, Size.length(255) );
actual = typeConfiguration.getDdlTypeRegistry().getTypeName( Types.BINARY, Size.length( 255) );
assertEquals(
"Wrong binary type. Should be varchar for length > 254",
"varchar(255) for bit data",

View File

@ -5,9 +5,6 @@ import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import java.util.List;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.junit.Assert.assertNotNull;
/**
@ -18,11 +15,7 @@ import static org.junit.Assert.assertNotNull;
public class DB2zDialectInitTestCase {
static class DB2zDialectWithExplicitTimezoneSupport extends DB2zDialect {
@Override
protected List<Integer> getSupportedJdbcTypeCodes() {
return List.of(TIMESTAMP_WITH_TIMEZONE);
}
}
}
@Test
public void testInitWithTimezoneSupport() {

View File

@ -19,6 +19,7 @@ import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.sequence.ANSISequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.DatabaseStructure;
@ -64,6 +65,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, PooledSequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
@ -110,6 +115,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, TableDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
@ -146,6 +155,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, SequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
@ -172,6 +185,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, PooledSequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
@ -204,6 +221,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, TableDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
@ -234,6 +255,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, SequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
@ -269,6 +294,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, SequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.OPT_PARAM, StandardOptimizerDescriptor.NONE.getExternalName() );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
@ -334,6 +363,10 @@ public class SequenceStyleConfigUnitTest {
.applySetting( AvailableSettings.DIALECT, PooledSequenceDialect.class.getName() )
.build()) {
MetadataBuildingContextTestingImpl buildingContext = new MetadataBuildingContextTestingImpl( serviceRegistry );
serviceRegistry.getService( JdbcServices.class ).getDialect().contributeTypes(
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
SequenceStyleGenerator generator = new SequenceStyleGenerator();

View File

@ -36,12 +36,7 @@ public class DefaultSchemaNameResolverTest {
ConnectionProxy.generateProxy( new ConnectionProxy( SCHEMA_NAME ) );
String schemaName = DefaultSchemaNameResolver.INSTANCE.resolveSchemaName(
connectionSupportsGetSchemaName,
new Dialect() {
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
}
new Dialect( ZERO_VERSION ) {}
);
assertEquals( SCHEMA_NAME, schemaName );
@ -49,12 +44,7 @@ public class DefaultSchemaNameResolverTest {
ConnectionProxy.generateProxy( new ConnectionProxy( null ) );
schemaName = DefaultSchemaNameResolver.INSTANCE.resolveSchemaName(
connectionNotSupportGetSchemaName,
new Dialect() {
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
new Dialect( ZERO_VERSION ) {
@Override
public String getCurrentSchemaCommand() {

View File

@ -99,10 +99,11 @@ public abstract class AbstractCriteriaLiteralHandlingModeTest extends BaseEntity
return getDialect().castPattern( CastType.OTHER, castType )
.replace(
"?2",
getDialect().getUnboundedTypeName(
typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.VARCHAR ),
typeConfiguration.getJavaTypeRegistry().getDescriptor( String.class )
)
typeConfiguration.getDdlTypeRegistry().getDescriptor( SqlTypes.VARCHAR )
.getCastTypeName(
typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.VARCHAR ),
typeConfiguration.getJavaTypeRegistry().getDescriptor( String.class )
)
)
.replace( "?1", expression );
}

View File

@ -57,12 +57,7 @@ public abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalT
return DialectContext.getDialect();
}
catch (Exception e) {
return new Dialect() {
@Override
public DatabaseVersion getVersion(){
return ZERO_VERSION;
}
};
return new Dialect( ZERO_VERSION ) {};
}
}

View File

@ -11,12 +11,14 @@ import java.util.Arrays;
import jakarta.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
import org.hibernate.orm.test.envers.Priority;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.Child1Entity;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.Child2Entity;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.ParentEntity;
import org.hibernate.orm.test.envers.tools.TestTools;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.junit.Assert;
import org.junit.Test;
@ -43,6 +45,8 @@ public class BasicSametable extends BaseEnversJPAFunctionalTestCase {
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
DdlTypeRegistry ddlTypeRegistry = em.unwrap( SessionImplementor.class ).getTypeConfiguration()
.getDdlTypeRegistry();
em.getTransaction().begin();
Session session = (Session) em.getDelegate();
@ -56,17 +60,17 @@ public class BasicSametable extends BaseEnversJPAFunctionalTestCase {
em.getTransaction().begin();
session = (Session) em.getDelegate();
session.createNativeQuery(
"CREATE TABLE children ( parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children ( parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
).executeUpdate();
session.createNativeQuery(
"CREATE TABLE children_AUD ( REV " + getDialect().getTypeName( Types.INTEGER ) + " NOT NULL" +
", REVEND " + getDialect().getTypeName( Types.INTEGER ) +
", REVTYPE " + getDialect().getTypeName( Types.TINYINT ) +
", parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children_AUD ( REV " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + " NOT NULL" +
", REVEND " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", REVTYPE " + ddlTypeRegistry.getTypeName( Types.TINYINT, getDialect() ) +
", parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
).executeUpdate();
em.getTransaction().commit();
em.clear();

View File

@ -17,6 +17,7 @@ import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.configuration.EnversSettings;
import org.hibernate.envers.strategy.ValidityAuditStrategy;
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
@ -26,6 +27,7 @@ import org.hibernate.orm.test.envers.entities.manytomany.sametable.Child2Entity;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.ParentEntity;
import org.hibernate.orm.test.envers.entities.reventity.CustomDateRevEntity;
import org.hibernate.orm.test.envers.tools.TestTools;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.junit.Test;
@ -68,6 +70,8 @@ public class ValidityAuditStrategyRevEndTestCustomRevEnt extends BaseEnversJPAFu
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
DdlTypeRegistry ddlTypeRegistry = em.unwrap( SessionImplementor.class ).getTypeConfiguration()
.getDdlTypeRegistry();
// We need first to modify the columns in the middle (join table) to
// allow null values. Hbm2ddl doesn't seem
@ -82,19 +86,19 @@ public class ValidityAuditStrategyRevEndTestCustomRevEnt extends BaseEnversJPAFu
em.getTransaction().begin();
session = (Session) em.getDelegate();
session.createNativeQuery(
"CREATE TABLE children ( parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children ( parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
)
.executeUpdate();
session.createNativeQuery(
"CREATE TABLE children_AUD ( REV " + getDialect().getTypeName( Types.INTEGER ) + " NOT NULL" +
", REVEND " + getDialect().getTypeName( Types.INTEGER ) +
", " + revendTimestampColumName + " " + getDialect().getTypeName( Types.TIMESTAMP ) +
", REVTYPE " + getDialect().getTypeName( Types.TINYINT ) +
", parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children_AUD ( REV " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + " NOT NULL" +
", REVEND " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", " + revendTimestampColumName + " " + ddlTypeRegistry.getTypeName( Types.TIMESTAMP, getDialect() ) +
", REVTYPE " + ddlTypeRegistry.getTypeName( Types.TINYINT, getDialect() ) +
", parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
)
.executeUpdate();
em.getTransaction().commit();

View File

@ -21,6 +21,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.SybaseASEDialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.configuration.EnversSettings;
import org.hibernate.envers.enhanced.SequenceIdRevisionEntity;
import org.hibernate.envers.strategy.ValidityAuditStrategy;
@ -30,6 +31,7 @@ import org.hibernate.orm.test.envers.entities.manytomany.sametable.Child1Entity;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.Child2Entity;
import org.hibernate.orm.test.envers.entities.manytomany.sametable.ParentEntity;
import org.hibernate.orm.test.envers.tools.TestTools;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.junit.Assert;
import org.junit.Test;
@ -68,6 +70,8 @@ public class ValidityAuditStrategyRevEndTsTest extends BaseEnversJPAFunctionalTe
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
DdlTypeRegistry ddlTypeRegistry = em.unwrap( SessionImplementor.class ).getTypeConfiguration()
.getDdlTypeRegistry();
// We need first to modify the columns in the middle (join table) to
// allow null values. Hbm2ddl doesn't seem
@ -82,19 +86,19 @@ public class ValidityAuditStrategyRevEndTsTest extends BaseEnversJPAFunctionalTe
em.getTransaction().begin();
session = (Session) em.getDelegate();
session.createNativeQuery(
"CREATE TABLE children ( parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children ( parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
)
.executeUpdate();
session.createNativeQuery(
"CREATE TABLE children_AUD ( REV " + getDialect().getTypeName( Types.INTEGER ) + " NOT NULL" +
", REVEND " + getDialect().getTypeName( Types.INTEGER ) +
", " + revendTimestampColumName + " " + getDialect().getTypeName( Types.TIMESTAMP ) +
", REVTYPE " + getDialect().getTypeName( Types.TINYINT ) +
", parent_id " + getDialect().getTypeName( Types.INTEGER ) +
", child1_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() +
", child2_id " + getDialect().getTypeName( Types.INTEGER ) + getDialect().getNullColumnString() + " )"
"CREATE TABLE children_AUD ( REV " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + " NOT NULL" +
", REVEND " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", " + revendTimestampColumName + " " + ddlTypeRegistry.getTypeName( Types.TIMESTAMP, getDialect() ) +
", REVTYPE " + ddlTypeRegistry.getTypeName( Types.TINYINT, getDialect() ) +
", parent_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) +
", child1_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() +
", child2_id " + ddlTypeRegistry.getTypeName( Types.INTEGER, getDialect() ) + getDialect().getNullColumnString() + " )"
)
.executeUpdate();
em.getTransaction().commit();

View File

@ -233,12 +233,7 @@ public class CustomRunner extends BlockJUnit4ClassRunner {
return DialectContext.getDialect();
}
catch (Exception e) {
return new Dialect() {
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
};
return new Dialect( ZERO_VERSION ) {};
}
}