"long" varchar/varbinary mappings
add Length class with useful constant values well-defined mappings for "long" varchar/varbinary types make LONGVARCHAR a synonym for VARCHAR with length=LONG32 make LONGVARBINARY a synonym for VARBINARY with length=LONG32 add Dialect.getMaxVarcharLength() + friends make schema validator ignore the differences between string types
This commit is contained in:
parent
f389952a9d
commit
0ca7a659b0
|
@ -109,7 +109,6 @@ public class SQLiteDialect extends Dialect {
|
||||||
|
|
||||||
registerColumnType( Types.BINARY, "blob" );
|
registerColumnType( Types.BINARY, "blob" );
|
||||||
registerColumnType( Types.VARBINARY, "blob" );
|
registerColumnType( Types.VARBINARY, "blob" );
|
||||||
registerColumnType( Types.LONGVARBINARY, "blob" );
|
|
||||||
uniqueDelegate = new SQLiteUniqueDelegate( this );
|
uniqueDelegate = new SQLiteUniqueDelegate( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,22 +55,18 @@ public class SybaseAnywhereDialect extends SybaseDialect {
|
||||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||||
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp with time zone" );
|
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp with time zone" );
|
||||||
|
|
||||||
final int maxStringLength = 32_767;
|
|
||||||
|
|
||||||
registerColumnType( Types.CHAR, maxStringLength, "char($l)" );
|
|
||||||
registerColumnType( Types.VARCHAR, maxStringLength, "varchar($l)" );
|
|
||||||
registerColumnType( Types.VARCHAR, "long varchar)" );
|
registerColumnType( Types.VARCHAR, "long varchar)" );
|
||||||
|
|
||||||
registerColumnType( Types.NCHAR, maxStringLength, "nchar($l)" );
|
|
||||||
registerColumnType( Types.NVARCHAR, maxStringLength, "nvarchar($l)" );
|
|
||||||
registerColumnType( Types.NVARCHAR, "long nvarchar)" );
|
registerColumnType( Types.NVARCHAR, "long nvarchar)" );
|
||||||
|
|
||||||
//note: 'binary' is actually a synonym for 'varbinary'
|
//note: 'binary' is actually a synonym for 'varbinary'
|
||||||
registerColumnType( Types.BINARY, maxStringLength, "binary($l)" );
|
|
||||||
registerColumnType( Types.VARBINARY, maxStringLength, "varbinary($l)" );
|
|
||||||
registerColumnType( Types.VARBINARY, "long binary)" );
|
registerColumnType( Types.VARBINARY, "long binary)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 32_767;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
return new StandardSqlAstTranslatorFactory() {
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a list of useful constant values that may be used
|
||||||
|
* to specify long column lengths in the JPA
|
||||||
|
* {@link jakarta.persistence.Column} annotation.
|
||||||
|
* <p>
|
||||||
|
* For example, {@code @Column(length=LONG16)} would specify
|
||||||
|
* that Hibernate should generate DDL with a column type
|
||||||
|
* capable of holding strings with 16-bit lengths.
|
||||||
|
*
|
||||||
|
* @see jakarta.persistence.Column#length()
|
||||||
|
*
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
public final class Length {
|
||||||
|
/**
|
||||||
|
* The default length for a column in JPA.
|
||||||
|
*
|
||||||
|
* @see jakarta.persistence.Column#length()
|
||||||
|
* @see org.hibernate.type.descriptor.java.JavaType#getDefaultSqlLength
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT = 255;
|
||||||
|
/**
|
||||||
|
* Used to select a variable-length SQL type large
|
||||||
|
* enough to contain values of maximum length 32600.
|
||||||
|
* This arbitrary-looking number was chosen because
|
||||||
|
* some databases support variable-length types
|
||||||
|
* right up to a limit that is just slightly below
|
||||||
|
* 32767. (For some, the limit is 32672 characters.)
|
||||||
|
* <p>
|
||||||
|
* This is also the default length for a column
|
||||||
|
* declared using
|
||||||
|
* {@code @JdbcTypeCode(Types.LONGVARCHAR)} or
|
||||||
|
* {@code @JdbcTypeCode(Types.LONGVARBINARY)}.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.type.descriptor.java.JavaType#getLongSqlLength
|
||||||
|
*/
|
||||||
|
public static final int LONG = 32_600;
|
||||||
|
/**
|
||||||
|
* The maximum length that fits in 16 bits.
|
||||||
|
* Used to select a variable-length SQL type large
|
||||||
|
* enough to contain values of maximum length 32767.
|
||||||
|
*/
|
||||||
|
public static final int LONG16 = Short.MAX_VALUE;
|
||||||
|
/**
|
||||||
|
* The maximum length of a Java string, that is,
|
||||||
|
* the maximum length that fits in 32 bits.
|
||||||
|
* Used to select a variable-length SQL type large
|
||||||
|
* enough to contain any Java string.
|
||||||
|
*/
|
||||||
|
public static final int LONG32 = Integer.MAX_VALUE;
|
||||||
|
/**
|
||||||
|
* The default length for a LOB column.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.dialect.Dialect#getDefaultLobLength
|
||||||
|
*/
|
||||||
|
public static final int LOB_DEFAULT = 1_048_576;
|
||||||
|
|
||||||
|
private Length() {}
|
||||||
|
}
|
|
@ -95,20 +95,23 @@ public class CockroachDialect extends Dialect {
|
||||||
|
|
||||||
registerColumnType( Types.TINYINT, "smallint" ); //no tinyint
|
registerColumnType( Types.TINYINT, "smallint" ); //no tinyint
|
||||||
|
|
||||||
|
//use 'string' instead of 'varchar'
|
||||||
|
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "string($l)");
|
||||||
|
registerColumnType( Types.VARCHAR, "string");
|
||||||
|
|
||||||
//no binary/varbinary
|
//no binary/varbinary
|
||||||
registerColumnType( Types.VARBINARY, "bytes" );
|
registerColumnType( Types.VARBINARY, "bytes" );
|
||||||
registerColumnType( Types.BINARY, "bytes" );
|
registerColumnType( Types.BINARY, "bytes" );
|
||||||
|
|
||||||
//no clob
|
//no clob
|
||||||
registerColumnType( Types.LONGVARCHAR, "string" );
|
|
||||||
registerColumnType( Types.CLOB, "string" );
|
registerColumnType( Types.CLOB, "string" );
|
||||||
|
|
||||||
//no nchar/nvarchar
|
//no nchar/nvarchar
|
||||||
registerColumnType( Types.NCHAR, "string($l)" );
|
registerColumnType( Types.NCHAR, "string($l)" );
|
||||||
registerColumnType( Types.NVARCHAR, "string($l)" );
|
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "string($l)" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "string");
|
||||||
|
|
||||||
//no nclob
|
//no nclob
|
||||||
registerColumnType( Types.LONGNVARCHAR, "string" );
|
|
||||||
registerColumnType( Types.NCLOB, "string" );
|
registerColumnType( Types.NCLOB, "string" );
|
||||||
|
|
||||||
registerColumnType( SqlTypes.UUID, "uuid" );
|
registerColumnType( SqlTypes.UUID, "uuid" );
|
||||||
|
|
|
@ -101,14 +101,16 @@ public class DB2Dialect extends Dialect {
|
||||||
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
|
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
|
||||||
|
|
||||||
if ( getVersion().isBefore( 11 ) ) {
|
if ( getVersion().isBefore( 11 ) ) {
|
||||||
registerColumnType( Types.BINARY, "varchar($l) for bit data" ); //should use 'binary' since version 11
|
|
||||||
registerColumnType( Types.BINARY, 254, "char($l) for bit data" ); //should use 'binary' since version 11
|
registerColumnType( Types.BINARY, 254, "char($l) for bit data" ); //should use 'binary' since version 11
|
||||||
registerColumnType( Types.VARBINARY, "varchar($l) for bit data" ); //should use 'varbinary' since version 11
|
registerColumnType( Types.BINARY, "varchar($l) for bit data" ); //should use 'binary' since version 11
|
||||||
|
|
||||||
|
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "varchar($l) for bit data" ); //should use 'varbinary' since version 11
|
||||||
|
|
||||||
//prior to DB2 11, the 'boolean' type existed,
|
//prior to DB2 11, the 'boolean' type existed,
|
||||||
//but was not allowed as a column type
|
//but was not allowed as a column type
|
||||||
registerColumnType( Types.BOOLEAN, "smallint" );
|
registerColumnType( Types.BOOLEAN, "smallint" );
|
||||||
}
|
}
|
||||||
|
registerColumnType( Types.VARBINARY, "blob($l)" );
|
||||||
|
|
||||||
registerColumnType( Types.BLOB, "blob($l)" );
|
registerColumnType( Types.BLOB, "blob($l)" );
|
||||||
registerColumnType( Types.CLOB, "clob($l)" );
|
registerColumnType( Types.CLOB, "clob($l)" );
|
||||||
|
@ -117,7 +119,8 @@ public class DB2Dialect extends Dialect {
|
||||||
registerColumnType( Types.TIME_WITH_TIMEZONE, "time" );
|
registerColumnType( Types.TIME_WITH_TIMEZONE, "time" );
|
||||||
|
|
||||||
// The long varchar data type was deprecated in DB2 and shouldn't be used anymore
|
// The long varchar data type was deprecated in DB2 and shouldn't be used anymore
|
||||||
registerColumnType( Types.LONGVARCHAR, "clob($l)" );
|
registerColumnType( Types.VARCHAR, "clob($l)" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "nclob($l)" );
|
||||||
|
|
||||||
//not keywords, at least not in DB2 11,
|
//not keywords, at least not in DB2 11,
|
||||||
//but perhaps they were in older versions?
|
//but perhaps they were in older versions?
|
||||||
|
@ -143,6 +146,11 @@ public class DB2Dialect extends Dialect {
|
||||||
return new DB2UniqueDelegate( this );
|
return new DB2UniqueDelegate( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 32_672;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseVersion getVersion() {
|
public DatabaseVersion getVersion() {
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -120,10 +120,11 @@ public class DerbyDialect extends Dialect {
|
||||||
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
|
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
|
||||||
|
|
||||||
registerColumnType( Types.BINARY, 254, "char($l) for bit data" );
|
registerColumnType( Types.BINARY, 254, "char($l) for bit data" );
|
||||||
registerColumnType( Types.BINARY, 32672, "varchar($l) for bit data" );
|
registerColumnType( Types.BINARY, getMaxVarbinaryLength(), "varchar($l) for bit data" );
|
||||||
registerColumnType( Types.BINARY, "long varchar for bit data" );
|
registerColumnType( Types.BINARY, "long varchar for bit data" );
|
||||||
registerColumnType( Types.VARBINARY, 32672, "varchar($l) for bit data" );
|
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "varchar($l) for bit data" );
|
||||||
registerColumnType( Types.VARBINARY, "long varchar for bit data" );
|
registerColumnType( Types.VARBINARY, 32_700,"long varchar for bit data" );
|
||||||
|
registerColumnType( Types.VARBINARY, "blob($l)" );
|
||||||
|
|
||||||
registerColumnType( Types.BLOB, "blob($l)" );
|
registerColumnType( Types.BLOB, "blob($l)" );
|
||||||
registerColumnType( Types.CLOB, "clob($l)" );
|
registerColumnType( Types.CLOB, "clob($l)" );
|
||||||
|
@ -131,7 +132,8 @@ public class DerbyDialect extends Dialect {
|
||||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||||
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
|
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
|
||||||
|
|
||||||
registerColumnType( Types.LONGVARCHAR, "long varchar" );
|
registerColumnType( Types.VARCHAR, 32_700, "long varchar" );
|
||||||
|
registerColumnType( Types.VARCHAR, "clob($l)" );
|
||||||
|
|
||||||
registerDerbyKeywords();
|
registerDerbyKeywords();
|
||||||
|
|
||||||
|
@ -142,6 +144,11 @@ public class DerbyDialect extends Dialect {
|
||||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
|
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 32_672;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName(int code, Size size) throws HibernateException {
|
public String getTypeName(int code, Size size) throws HibernateException {
|
||||||
if ( code == Types.CHAR ) {
|
if ( code == Types.CHAR ) {
|
||||||
|
|
|
@ -221,7 +221,41 @@ public abstract class Dialect implements ConversionContext {
|
||||||
// constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
protected Dialect() {
|
protected Dialect() {
|
||||||
|
this(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Dialect(boolean autoRegisterColumnTypes) {
|
||||||
|
uniqueDelegate = new DefaultUniqueDelegate( this );
|
||||||
|
sizeStrategy = new SizeStrategyImpl();
|
||||||
|
if (autoRegisterColumnTypes) {
|
||||||
|
registerDefaultColumnTypes();
|
||||||
|
}
|
||||||
|
registerHibernateTypes();
|
||||||
|
registerDefaultKeywords();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerDefaultColumnTypes() {
|
||||||
|
registerDefaultColumnTypes( getMaxVarcharLength(), getMaxNVarcharLength(), getMaxVarbinaryLength() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>
|
||||||
|
* Note that {@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}. Concrete dialects
|
||||||
|
* should usually avoid registering mappings for these JDBC types.
|
||||||
|
*
|
||||||
|
* @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) {
|
||||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||||
|
|
||||||
registerColumnType( Types.TINYINT, "tinyint" );
|
registerColumnType( Types.TINYINT, "tinyint" );
|
||||||
|
@ -249,17 +283,19 @@ public abstract class Dialect implements ConversionContext {
|
||||||
registerColumnType( Types.TIME_WITH_TIMEZONE, "time with time zone" );
|
registerColumnType( Types.TIME_WITH_TIMEZONE, "time with time zone" );
|
||||||
|
|
||||||
registerColumnType( Types.BINARY, "binary($l)" );
|
registerColumnType( Types.BINARY, "binary($l)" );
|
||||||
registerColumnType( Types.VARBINARY, "varbinary($l)" );
|
registerColumnType( Types.VARBINARY, maxVarBinaryLength, "varbinary($l)" );
|
||||||
registerColumnType( Types.BLOB, "blob" );
|
registerColumnType( Types.BLOB, "blob" );
|
||||||
|
|
||||||
registerColumnType( Types.CHAR, "char($l)" );
|
registerColumnType( Types.CHAR, "char($l)" );
|
||||||
registerColumnType( Types.VARCHAR, "varchar($l)" );
|
registerColumnType( Types.VARCHAR, maxVarcharLength, "varchar($l)" );
|
||||||
registerColumnType( Types.CLOB, "clob" );
|
registerColumnType( Types.CLOB, "clob" );
|
||||||
|
|
||||||
registerColumnType( Types.NCHAR, "nchar($l)" );
|
registerColumnType( Types.NCHAR, "nchar($l)" );
|
||||||
registerColumnType( Types.NVARCHAR, "nvarchar($l)" );
|
registerColumnType( Types.NVARCHAR, maxNVarcharLength, "nvarchar($l)" );
|
||||||
registerColumnType( Types.NCLOB, "nclob" );
|
registerColumnType( Types.NCLOB, "nclob" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerHibernateTypes() {
|
||||||
// register hibernate types for default use in scalar sqlquery type auto detection
|
// register hibernate types for default use in scalar sqlquery type auto detection
|
||||||
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() );
|
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() );
|
||||||
|
|
||||||
|
@ -298,11 +334,6 @@ public abstract class Dialect implements ConversionContext {
|
||||||
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() );
|
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() );
|
||||||
registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getName() );
|
registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getName() );
|
||||||
registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getName() );
|
registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getName() );
|
||||||
|
|
||||||
registerDefaultKeywords();
|
|
||||||
|
|
||||||
uniqueDelegate = new DefaultUniqueDelegate( this );
|
|
||||||
sizeStrategy = new SizeStrategyImpl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerDefaultKeywords() {
|
protected void registerDefaultKeywords() {
|
||||||
|
@ -382,7 +413,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the given JDBC type code represent some sort of
|
* Does the given JDBC type code represent some sort of
|
||||||
* string type?
|
* character string type?
|
||||||
* @param sqlType a JDBC type code from {@link Types}
|
* @param sqlType a JDBC type code from {@link Types}
|
||||||
*/
|
*/
|
||||||
private static boolean isCharacterType(int sqlType) {
|
private static boolean isCharacterType(int sqlType) {
|
||||||
|
@ -399,6 +430,38 @@ public abstract class Dialect implements ConversionContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the given JDBC type code represent some sort of
|
||||||
|
* variable-length character string type?
|
||||||
|
* @param sqlType a JDBC type code from {@link Types}
|
||||||
|
*/
|
||||||
|
private static boolean isVarcharType(int sqlType) {
|
||||||
|
switch (sqlType) {
|
||||||
|
case Types.VARCHAR:
|
||||||
|
case Types.LONGVARCHAR:
|
||||||
|
case Types.NVARCHAR:
|
||||||
|
case Types.LONGNVARCHAR:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the given JDBC type code represent some sort of
|
||||||
|
* variable-length binary string type?
|
||||||
|
* @param sqlType a JDBC type code from {@link Types}
|
||||||
|
*/
|
||||||
|
private static boolean isVarbinaryType(int sqlType) {
|
||||||
|
switch (sqlType) {
|
||||||
|
case Types.VARBINARY:
|
||||||
|
case Types.LONGVARBINARY:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a SQL check condition for a column that represents a boolean value.
|
* Render a SQL check condition for a column that represents a boolean value.
|
||||||
*/
|
*/
|
||||||
|
@ -1021,12 +1084,20 @@ public abstract class Dialect implements ConversionContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the given JDBC type codes, as defined in {@link Types} represent
|
* Do the given JDBC type codes, as defined in {@link Types} represent
|
||||||
* essentially the same type in this dialect of SQL? The default
|
* essentially the same type in this dialect of SQL?
|
||||||
* implementation treats {@link Types#NUMERIC NUMERIC} and
|
* <p>
|
||||||
|
* The default implementation treats {@link Types#NUMERIC NUMERIC} and
|
||||||
* {@link Types#DECIMAL DECIMAL} as the same type, and
|
* {@link Types#DECIMAL DECIMAL} as the same type, and
|
||||||
* {@link Types#FLOAT FLOAT}, {@link Types#REAL REAL}, and
|
* {@link Types#FLOAT FLOAT}, {@link Types#REAL REAL}, and
|
||||||
* {@link Types#DOUBLE DOUBLE} as essentially the same type, since the
|
* {@link Types#DOUBLE DOUBLE} as essentially the same type, since the
|
||||||
* ANSI SQL specification fails to meaningfully distinguish them.
|
* ANSI SQL specification fails to meaningfully distinguish them.
|
||||||
|
* <p>
|
||||||
|
* The default implementation also treats {@link Types#VARCHAR VARCHAR},
|
||||||
|
* {@link Types#NVARCHAR NVARCHAR}, {@link Types#LONGVARCHAR LONGVARCHAR},
|
||||||
|
* and {@link Types#LONGNVARCHAR LONGNVARCHAR} as the same type, and
|
||||||
|
* {@link Types#VARBINARY BINARY} and
|
||||||
|
* {@link Types#LONGVARBINARY LONGVARBINARY} as the same type, since
|
||||||
|
* Hibernate doesn't really differentiate these types.
|
||||||
*
|
*
|
||||||
* @param typeCode1 the first JDBC type code
|
* @param typeCode1 the first JDBC type code
|
||||||
* @param typeCode2 the second JDBC type code
|
* @param typeCode2 the second JDBC type code
|
||||||
|
@ -1036,7 +1107,9 @@ public abstract class Dialect implements ConversionContext {
|
||||||
public boolean equivalentTypes(int typeCode1, int typeCode2) {
|
public boolean equivalentTypes(int typeCode1, int typeCode2) {
|
||||||
return typeCode1==typeCode2
|
return typeCode1==typeCode2
|
||||||
|| isNumericOrDecimal(typeCode1) && isNumericOrDecimal(typeCode2)
|
|| isNumericOrDecimal(typeCode1) && isNumericOrDecimal(typeCode2)
|
||||||
|| isFloatOrRealOrDouble(typeCode1) && isFloatOrRealOrDouble(typeCode2);
|
|| isFloatOrRealOrDouble(typeCode1) && isFloatOrRealOrDouble(typeCode2)
|
||||||
|
|| isVarcharType(typeCode1) && isVarcharType(typeCode2)
|
||||||
|
|| isVarbinaryType(typeCode1) && isVarbinaryType(typeCode2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNumericOrDecimal(int typeCode) {
|
private static boolean isNumericOrDecimal(int typeCode) {
|
||||||
|
@ -1152,6 +1225,10 @@ public abstract class Dialect implements ConversionContext {
|
||||||
String result = typeNames.get( code, size.getLength(), size.getPrecision(), size.getScale() );
|
String result = typeNames.get( code, size.getLength(), size.getPrecision(), size.getScale() );
|
||||||
if ( result == null ) {
|
if ( result == null ) {
|
||||||
switch ( code ) {
|
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:
|
case Types.LONGVARCHAR:
|
||||||
return getTypeName( Types.VARCHAR, size );
|
return getTypeName( Types.VARCHAR, size );
|
||||||
case Types.LONGNVARCHAR:
|
case Types.LONGNVARCHAR:
|
||||||
|
@ -3467,6 +3544,36 @@ public abstract class Dialect implements ConversionContext {
|
||||||
return sizeStrategy;
|
return sizeStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The longest possible length of a {@link java.sql.Types#VARCHAR}-like column.
|
||||||
|
* For longer column lengths, use some sort of {@code text}-like type for the
|
||||||
|
* column.
|
||||||
|
*/
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
//the longest possible length of a Java string
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The longest possible length of a {@link java.sql.Types#NVARCHAR}-like column.
|
||||||
|
* For longer column lengths, use some sort of {@code text}-like type for the
|
||||||
|
* column.
|
||||||
|
*/
|
||||||
|
public int getMaxNVarcharLength() {
|
||||||
|
//for most databases it's the same as for VARCHAR
|
||||||
|
return getMaxVarcharLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The longest possible length of a {@link java.sql.Types#VARBINARY}-like column.
|
||||||
|
* For longer column lengths, use some sort of {@code image}-like type for the
|
||||||
|
* column.
|
||||||
|
*/
|
||||||
|
public int getMaxVarbinaryLength() {
|
||||||
|
//for most databases it's the same as for VARCHAR
|
||||||
|
return getMaxVarcharLength();
|
||||||
|
}
|
||||||
|
|
||||||
public long getDefaultLobLength() {
|
public long getDefaultLobLength() {
|
||||||
return Size.DEFAULT_LOB_LENGTH;
|
return Size.DEFAULT_LOB_LENGTH;
|
||||||
}
|
}
|
||||||
|
@ -3634,7 +3741,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
switch (jdbcTypeCode) {
|
switch (jdbcTypeCode) {
|
||||||
case Types.BIT:
|
case Types.BIT:
|
||||||
// Use the default length for Boolean if we encounter the JPA default 255 instead
|
// Use the default length for Boolean if we encounter the JPA default 255 instead
|
||||||
if ( javaType.getJavaTypeClass() == Boolean.class && length != null && length == 255 ) {
|
if ( javaType.getJavaTypeClass() == Boolean.class && length != null && length == Size.DEFAULT_LENGTH ) {
|
||||||
length = null;
|
length = null;
|
||||||
}
|
}
|
||||||
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
|
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
|
||||||
|
@ -3642,7 +3749,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
case Types.CHAR:
|
case Types.CHAR:
|
||||||
case Types.NCHAR:
|
case Types.NCHAR:
|
||||||
// Use the default length for char and UUID if we encounter the JPA default 255 instead
|
// Use the default length for char and UUID if we encounter the JPA default 255 instead
|
||||||
if ( length != null && length == 255 ) {
|
if ( length != null && length == Size.DEFAULT_LENGTH ) {
|
||||||
if ( javaType.getJavaTypeClass() == Character.class || javaType.getJavaTypeClass() == UUID.class ) {
|
if ( javaType.getJavaTypeClass() == Character.class || javaType.getJavaTypeClass() == UUID.class ) {
|
||||||
length = null;
|
length = null;
|
||||||
}
|
}
|
||||||
|
@ -3654,7 +3761,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
case Types.BINARY:
|
case Types.BINARY:
|
||||||
case Types.VARBINARY:
|
case Types.VARBINARY:
|
||||||
// Use the default length for UUID if we encounter the JPA default 255 instead
|
// Use the default length for UUID if we encounter the JPA default 255 instead
|
||||||
if ( javaType.getJavaTypeClass() == UUID.class && length != null && length == 255 ) {
|
if ( javaType.getJavaTypeClass() == UUID.class && length != null && length == Size.DEFAULT_LENGTH ) {
|
||||||
length = null;
|
length = null;
|
||||||
}
|
}
|
||||||
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
|
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
|
||||||
|
|
|
@ -128,7 +128,12 @@ public class H2Dialect extends Dialect {
|
||||||
// http://code.google.com/p/h2database/issues/detail?id=235
|
// http://code.google.com/p/h2database/issues/detail?id=235
|
||||||
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||||
|
|
||||||
|
registerColumnType( Types.VARCHAR, "varchar" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "varchar" );
|
||||||
|
registerColumnType( Types.VARBINARY, "varbinary" );
|
||||||
|
|
||||||
registerColumnType( SqlTypes.ARRAY, "array" );
|
registerColumnType( SqlTypes.ARRAY, "array" );
|
||||||
|
|
||||||
if ( version.isSameOrAfter( 1, 4, 32 ) ) {
|
if ( version.isSameOrAfter( 1, 4, 32 ) ) {
|
||||||
this.sequenceInformationExtractor = version.isSameOrAfter( 1, 4, 201 )
|
this.sequenceInformationExtractor = version.isSameOrAfter( 1, 4, 201 )
|
||||||
? SequenceInformationExtractorLegacyImpl.INSTANCE
|
? SequenceInformationExtractorLegacyImpl.INSTANCE
|
||||||
|
@ -240,6 +245,11 @@ public class H2Dialect extends Dialect {
|
||||||
CommonFunctionFactory.rownum( queryEngine );
|
CommonFunctionFactory.rownum( queryEngine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 1_048_576;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentTime() {
|
public String currentTime() {
|
||||||
return useLocalTime ? "localtime" : super.currentTime();
|
return useLocalTime ? "localtime" : super.currentTime();
|
||||||
|
|
|
@ -47,12 +47,10 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
|
||||||
public HANAColumnStoreDialect(DatabaseVersion version) {
|
public HANAColumnStoreDialect(DatabaseVersion version) {
|
||||||
super( version );
|
super( version );
|
||||||
if ( version.isSameOrAfter( 4 ) ) {
|
if ( version.isSameOrAfter( 4 ) ) {
|
||||||
registerColumnType( Types.CHAR, "nvarchar(1)" );
|
registerColumnType( Types.CHAR, "nvarchar($l)" );
|
||||||
registerColumnType( Types.VARCHAR, 5000, "nvarchar($l)" );
|
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "nvarchar($l)" );
|
||||||
registerColumnType( Types.LONGVARCHAR, 5000, "nvarchar($l)" );
|
|
||||||
|
|
||||||
// for longer values map to clob/nclob
|
// for longer values map to clob/nclob
|
||||||
registerColumnType( Types.LONGVARCHAR, "nclob" );
|
|
||||||
registerColumnType( Types.VARCHAR, "nclob" );
|
registerColumnType( Types.VARCHAR, "nclob" );
|
||||||
registerColumnType( Types.CLOB, "nclob" );
|
registerColumnType( Types.CLOB, "nclob" );
|
||||||
|
|
||||||
|
@ -69,6 +67,11 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 5000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseVersion getVersion(){
|
public DatabaseVersion getVersion(){
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -60,10 +60,6 @@ public class MariaDBDialect extends MySQLDialect {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getMaxVarcharLen() {
|
|
||||||
return getMySQLVersion().isBefore( 5 ) ? 255 : 65_534;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseVersion getVersion() {
|
public DatabaseVersion getVersion() {
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -105,10 +105,12 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySQLDialect(DatabaseVersion version, int characterSetBytesPerCharacter) {
|
public MySQLDialect(DatabaseVersion version, int characterSetBytesPerCharacter) {
|
||||||
super();
|
super(false);
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.characterSetBytesPerCharacter = characterSetBytesPerCharacter;
|
this.characterSetBytesPerCharacter = characterSetBytesPerCharacter;
|
||||||
|
|
||||||
|
registerDefaultColumnTypes();
|
||||||
|
|
||||||
String storageEngine = Environment.getProperties().getProperty( Environment.STORAGE_ENGINE );
|
String storageEngine = Environment.getProperties().getProperty( Environment.STORAGE_ENGINE );
|
||||||
if (storageEngine == null) {
|
if (storageEngine == null) {
|
||||||
storageEngine = System.getProperty( Environment.STORAGE_ENGINE );
|
storageEngine = System.getProperty( Environment.STORAGE_ENGINE );
|
||||||
|
@ -141,41 +143,40 @@ public class MySQLDialect extends Dialect {
|
||||||
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamp($p)");
|
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamp($p)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// max length for VARCHAR changed in 5.0.3
|
|
||||||
final int maxVarcharLen = getMaxVarcharLen();
|
|
||||||
|
|
||||||
registerColumnType( Types.VARCHAR, maxVarcharLen, "varchar($l)" );
|
|
||||||
registerColumnType( Types.VARBINARY, maxVarcharLen, "varbinary($l)" );
|
|
||||||
|
|
||||||
final int maxTinyLobLen = 255;
|
final int maxTinyLobLen = 255;
|
||||||
final int maxLobLen = 65_535;
|
final int maxLobLen = 65_535;
|
||||||
final int maxMediumLobLen = 16_777_215;
|
final int maxMediumLobLen = 16_777_215;
|
||||||
final long maxLongLobLen = 4_294_967_295L;
|
//the maximum long LOB length is 4_294_967_295, bigger than any Java string
|
||||||
|
|
||||||
registerColumnType( Types.VARCHAR, maxLongLobLen, "longtext" );
|
registerColumnType( Types.VARCHAR, "longtext" );
|
||||||
registerColumnType( Types.VARCHAR, maxMediumLobLen, "mediumtext" );
|
registerColumnType( Types.VARCHAR, maxMediumLobLen, "mediumtext" );
|
||||||
if ( maxVarcharLen < maxLobLen ) {
|
if ( getMaxVarcharLength() < maxLobLen ) {
|
||||||
registerColumnType( Types.VARCHAR, maxLobLen, "text" );
|
registerColumnType( Types.VARCHAR, maxLobLen, "text" );
|
||||||
}
|
}
|
||||||
|
|
||||||
registerColumnType( Types.VARBINARY, maxLongLobLen, "longblob" );
|
registerColumnType( Types.NVARCHAR, "longtext" );
|
||||||
|
registerColumnType( Types.NVARCHAR, maxMediumLobLen, "mediumtext" );
|
||||||
|
if ( getMaxNVarcharLength() < maxLobLen ) {
|
||||||
|
registerColumnType( Types.NVARCHAR, maxLobLen, "text" );
|
||||||
|
}
|
||||||
|
|
||||||
|
registerColumnType( Types.VARBINARY, "longblob" );
|
||||||
registerColumnType( Types.VARBINARY, maxMediumLobLen, "mediumblob" );
|
registerColumnType( Types.VARBINARY, maxMediumLobLen, "mediumblob" );
|
||||||
if ( maxVarcharLen < maxLobLen ) {
|
if ( getMaxVarbinaryLength() < maxLobLen ) {
|
||||||
registerColumnType( Types.VARBINARY, maxLobLen, "blob" );
|
registerColumnType( Types.VARBINARY, maxLobLen, "blob" );
|
||||||
}
|
}
|
||||||
|
|
||||||
registerColumnType( Types.BLOB, maxLongLobLen, "longblob" );
|
registerColumnType( Types.BLOB, "longblob" );
|
||||||
registerColumnType( Types.BLOB, maxMediumLobLen, "mediumblob" );
|
registerColumnType( Types.BLOB, maxMediumLobLen, "mediumblob" );
|
||||||
registerColumnType( Types.BLOB, maxLobLen, "blob" );
|
registerColumnType( Types.BLOB, maxLobLen, "blob" );
|
||||||
registerColumnType( Types.BLOB, maxTinyLobLen, "tinyblob" );
|
registerColumnType( Types.BLOB, maxTinyLobLen, "tinyblob" );
|
||||||
|
|
||||||
registerColumnType( Types.CLOB, maxLongLobLen, "longtext" );
|
registerColumnType( Types.CLOB, "longtext" );
|
||||||
registerColumnType( Types.CLOB, maxMediumLobLen, "mediumtext" );
|
registerColumnType( Types.CLOB, maxMediumLobLen, "mediumtext" );
|
||||||
registerColumnType( Types.CLOB, maxLobLen, "text" );
|
registerColumnType( Types.CLOB, maxLobLen, "text" );
|
||||||
registerColumnType( Types.CLOB, maxTinyLobLen, "tinytext" );
|
registerColumnType( Types.CLOB, maxTinyLobLen, "tinytext" );
|
||||||
|
|
||||||
registerColumnType( Types.NCLOB, "longtext" );
|
registerColumnType( Types.NCLOB, "longtext" );
|
||||||
registerColumnType( Types.NCLOB, maxLongLobLen, "longtext" );
|
|
||||||
registerColumnType( Types.NCLOB, maxMediumLobLen, "mediumtext" );
|
registerColumnType( Types.NCLOB, maxMediumLobLen, "mediumtext" );
|
||||||
registerColumnType( Types.NCLOB, maxLobLen, "text" );
|
registerColumnType( Types.NCLOB, maxLobLen, "text" );
|
||||||
registerColumnType( Types.NCLOB, maxTinyLobLen, "tinytext" );
|
registerColumnType( Types.NCLOB, maxTinyLobLen, "tinytext" );
|
||||||
|
@ -253,7 +254,9 @@ public class MySQLDialect extends Dialect {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getMaxVarcharLen() {
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
// max length for VARCHAR changed in 5.0.3
|
||||||
if ( getMySQLVersion().isBefore( 5 ) ) {
|
if ( getMySQLVersion().isBefore( 5 ) ) {
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
@ -272,6 +275,11 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarbinaryLength() {
|
||||||
|
return getMySQLVersion().isBefore( 5 ) ? 255 : 65_535;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNullColumnString(String columnType) {
|
public String getNullColumnString(String columnType) {
|
||||||
// Good job MySQL https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html
|
// Good job MySQL https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html
|
||||||
|
|
|
@ -199,6 +199,19 @@ public class OracleDialect extends Dialect {
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
//with MAX_STRING_SIZE=EXTENDED, changes to 32_767
|
||||||
|
//TODO: provide a way to change this without a custom Dialect
|
||||||
|
return 4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarbinaryLength() {
|
||||||
|
//with MAX_STRING_SIZE=EXTENDED, changes to 32_767
|
||||||
|
return 2000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
return new StandardSqlAstTranslatorFactory() {
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@ -525,16 +538,17 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
protected void registerCharacterTypeMappings() {
|
protected void registerCharacterTypeMappings() {
|
||||||
if ( getVersion().isBefore( 9 ) ) {
|
if ( getVersion().isBefore( 9 ) ) {
|
||||||
registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
|
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "varchar2($l)" );
|
||||||
registerColumnType( Types.VARCHAR, "clob" );
|
registerColumnType( Types.VARCHAR, "clob" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
registerColumnType( Types.CHAR, "char($l char)" );
|
registerColumnType( Types.CHAR, "char($l char)" );
|
||||||
registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
|
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "varchar2($l char)" );
|
||||||
registerColumnType( Types.VARCHAR, "clob" );
|
registerColumnType( Types.VARCHAR, "clob" );
|
||||||
registerColumnType( Types.NVARCHAR, 4000, "nvarchar2($l)" );
|
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "nvarchar2($l)" );
|
||||||
registerColumnType( Types.NVARCHAR, "nclob" );
|
registerColumnType( Types.NVARCHAR, "nclob" );
|
||||||
}
|
}
|
||||||
|
//note: the 'long' type is deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerNumericTypeMappings() {
|
protected void registerNumericTypeMappings() {
|
||||||
|
@ -576,10 +590,10 @@ public class OracleDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerBinaryTypeMappings() {
|
protected void registerBinaryTypeMappings() {
|
||||||
registerColumnType( Types.BINARY, 2000, "raw($l)" );
|
registerColumnType( Types.BINARY, getMaxVarbinaryLength(), "raw($l)" );
|
||||||
registerColumnType( Types.BINARY, "blob" );
|
registerColumnType( Types.BINARY, "blob" );
|
||||||
|
|
||||||
registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
|
registerColumnType( Types.VARBINARY, getMaxVarbinaryLength(), "raw($l)" );
|
||||||
registerColumnType( Types.VARBINARY, "blob" );
|
registerColumnType( Types.VARBINARY, "blob" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,13 +132,13 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
|
|
||||||
//there are no nchar/nvarchar types in Postgres
|
//there are no nchar/nvarchar types in Postgres
|
||||||
registerColumnType( Types.NCHAR, "char($l)" );
|
registerColumnType( Types.NCHAR, "char($l)" );
|
||||||
registerColumnType( Types.NVARCHAR, "varchar($l)" );
|
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "varchar($l)" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "text" );
|
||||||
|
|
||||||
//since there's no real difference between
|
// since there's no real difference between TEXT and VARCHAR,
|
||||||
//TEXT and VARCHAR, except for the length limit,
|
// except for the length limit, we can just use 'text' for the
|
||||||
//we can just use 'text' for the "long" types
|
// "long" string types
|
||||||
registerColumnType( Types.LONGVARCHAR, "text" );
|
registerColumnType( Types.VARCHAR, "text" );
|
||||||
registerColumnType( Types.LONGNVARCHAR, "text" );
|
|
||||||
|
|
||||||
registerColumnType( SqlTypes.INET, "inet" );
|
registerColumnType( SqlTypes.INET, "inet" );
|
||||||
registerColumnType( SqlTypes.INTERVAL_SECOND, "interval second($s)" );
|
registerColumnType( SqlTypes.INTERVAL_SECOND, "interval second($s)" );
|
||||||
|
@ -163,6 +163,17 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
getDefaultProperties().setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
getDefaultProperties().setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 10_485_760;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarbinaryLength() {
|
||||||
|
//postgres has no varbinary-like type
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName(int code, Size size) throws HibernateException {
|
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
|
// The maximum scale for `interval second` is 6 unfortunately so we have to use numeric by default
|
||||||
|
|
|
@ -66,7 +66,6 @@ import java.util.TimeZone;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import static java.util.regex.Pattern.compile;
|
|
||||||
import static org.hibernate.query.TemporalUnit.NANOSECOND;
|
import static org.hibernate.query.TemporalUnit.NANOSECOND;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
|
@ -113,13 +112,10 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||||
exporter = new SqlServerSequenceExporter( this );
|
exporter = new SqlServerSequenceExporter( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
registerColumnType( Types.VARCHAR, 8000, "varchar($l)" );
|
|
||||||
registerColumnType( Types.NVARCHAR, 4000, "nvarchar($l)" );
|
|
||||||
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
|
|
||||||
|
|
||||||
if ( getVersion().isBefore( 9 ) ) {
|
if ( getVersion().isBefore( 9 ) ) {
|
||||||
registerColumnType( Types.VARBINARY, "image" );
|
registerColumnType( Types.VARBINARY, "image" );
|
||||||
registerColumnType( Types.VARCHAR, "text" );
|
registerColumnType( Types.VARCHAR, "text" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "text" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
@ -146,6 +142,16 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||||
registerKeyword( "key" );
|
registerKeyword( "key" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
return 8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxNVarcharLength() {
|
||||||
|
return 4000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseVersion getVersion() {
|
public DatabaseVersion getVersion() {
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -92,17 +92,20 @@ public class SpannerDialect extends Dialect {
|
||||||
//there is no time type of any kind
|
//there is no time type of any kind
|
||||||
registerColumnType( Types.TIME, "timestamp" );
|
registerColumnType( Types.TIME, "timestamp" );
|
||||||
|
|
||||||
final int stringMaxLength = 2_621_440;
|
registerColumnType( Types.CHAR, getMaxVarcharLength(), "string($l)" );
|
||||||
final int bytesMaxLength = 10_485_760;
|
registerColumnType( Types.CHAR, "string(max)" );
|
||||||
|
registerColumnType( Types.VARCHAR, getMaxVarcharLength(), "string($l)" );
|
||||||
|
registerColumnType( Types.VARCHAR, "string(max)" );
|
||||||
|
|
||||||
registerColumnType( Types.CHAR, stringMaxLength, "string($l)" );
|
registerColumnType( Types.NCHAR, getMaxNVarcharLength(), "string($l)" );
|
||||||
registerColumnType( Types.VARCHAR, stringMaxLength, "string($l)" );
|
registerColumnType( Types.NCHAR, "string(max)" );
|
||||||
|
registerColumnType( Types.NVARCHAR, getMaxNVarcharLength(), "string($l)" );
|
||||||
|
registerColumnType( Types.NVARCHAR, "string(max)" );
|
||||||
|
|
||||||
registerColumnType( Types.NCHAR, stringMaxLength, "string($l)" );
|
registerColumnType( Types.BINARY, getMaxBytesLength(), "bytes($l)" );
|
||||||
registerColumnType( Types.NVARCHAR, stringMaxLength, "string($l)" );
|
registerColumnType( Types.BINARY, "bytes(max)" );
|
||||||
|
registerColumnType( Types.VARBINARY, getMaxBytesLength(), "bytes($l)" );
|
||||||
registerColumnType( Types.BINARY, bytesMaxLength, "bytes($l)" );
|
registerColumnType( Types.VARBINARY, "bytes(max)" );
|
||||||
registerColumnType( Types.VARBINARY, bytesMaxLength, "bytes($l)" );
|
|
||||||
|
|
||||||
registerColumnType( Types.CLOB, "string(max)" );
|
registerColumnType( Types.CLOB, "string(max)" );
|
||||||
registerColumnType( Types.NCLOB, "string(max)" );
|
registerColumnType( Types.NCLOB, "string(max)" );
|
||||||
|
@ -114,6 +117,17 @@ public class SpannerDialect extends Dialect {
|
||||||
registerKeywords( info );
|
registerKeywords( info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
//max is equivalent to 2_621_440
|
||||||
|
return 2_621_440;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxBytesLength() {
|
||||||
|
//max is equivalent to 10_485_760
|
||||||
|
return 10_485_760;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseVersion getVersion() {
|
public DatabaseVersion getVersion() {
|
||||||
return ZERO_VERSION;
|
return ZERO_VERSION;
|
||||||
|
|
|
@ -99,12 +99,8 @@ public class SybaseASEDialect extends SybaseDialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the maximum length of a VARCHAR or VARBINARY
|
registerColumnType( Types.VARBINARY, "image" );
|
||||||
// depends on the page size, and also on the
|
registerColumnType( Types.VARCHAR, "text" );
|
||||||
// version of Sybase ASE, and can be quite small,
|
|
||||||
// so use 'image' and 'text' as the "long" types
|
|
||||||
registerColumnType( Types.LONGVARBINARY, "image" );
|
|
||||||
registerColumnType( Types.LONGVARCHAR, "text" );
|
|
||||||
|
|
||||||
registerSybaseKeywords();
|
registerSybaseKeywords();
|
||||||
sizeStrategy = new SizeStrategyImpl() {
|
sizeStrategy = new SizeStrategyImpl() {
|
||||||
|
@ -127,6 +123,17 @@ public class SybaseASEDialect extends SybaseDialect {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVarcharLength() {
|
||||||
|
// the maximum length of a VARCHAR or VARBINARY
|
||||||
|
// column depends on the page size and ASE version
|
||||||
|
// and is actually a limit on the whole row length,
|
||||||
|
// not the individual column length -- anyway, the
|
||||||
|
// largest possible page size is 16k, so that's a
|
||||||
|
// hard upper limit
|
||||||
|
return 16_384;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isAnsiNull(DatabaseMetaData databaseMetaData) {
|
private static boolean isAnsiNull(DatabaseMetaData databaseMetaData) {
|
||||||
if ( databaseMetaData != null ) {
|
if ( databaseMetaData != null ) {
|
||||||
try (java.sql.Statement s = databaseMetaData.getConnection().createStatement() ) {
|
try (java.sql.Statement s = databaseMetaData.getConnection().createStatement() ) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc;
|
package org.hibernate.engine.jdbc;
|
||||||
|
|
||||||
|
import org.hibernate.Length;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,9 +37,9 @@ public class Size implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final long DEFAULT_LENGTH = 255;
|
public static final long DEFAULT_LENGTH = Length.DEFAULT;
|
||||||
public static final long LONG_LENGTH = 65_535;
|
public static final long LONG_LENGTH = Length.LONG;
|
||||||
public static final long DEFAULT_LOB_LENGTH = 1_048_576;
|
public static final long DEFAULT_LOB_LENGTH = Length.LOB_DEFAULT;
|
||||||
public static final int DEFAULT_PRECISION = 19;
|
public static final int DEFAULT_PRECISION = 19;
|
||||||
public static final int DEFAULT_SCALE = 2;
|
public static final int DEFAULT_SCALE = 2;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.hibernate.boot.model.relational.internal.SqlStringGenerationContextIm
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Selectable;
|
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
|
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
|
||||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||||
|
@ -48,12 +47,7 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
|
||||||
HibernateSchemaManagementTool tool,
|
HibernateSchemaManagementTool tool,
|
||||||
SchemaFilter validateFilter) {
|
SchemaFilter validateFilter) {
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
if ( validateFilter == null ) {
|
this.schemaFilter = validateFilter == null ? DefaultSchemaFilter.INSTANCE : validateFilter;
|
||||||
this.schemaFilter = DefaultSchemaFilter.INSTANCE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.schemaFilter = validateFilter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -143,23 +137,20 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Iterator selectableItr = table.getColumnIterator();
|
final Iterator<Column> columnIter = table.getColumnIterator();
|
||||||
while ( selectableItr.hasNext() ) {
|
while ( columnIter.hasNext() ) {
|
||||||
final Selectable selectable = (Selectable) selectableItr.next();
|
final Column column = columnIter.next();
|
||||||
if ( Column.class.isInstance( selectable ) ) {
|
final ColumnInformation existingColumn = tableInformation.getColumn( Identifier.toIdentifier( column.getQuotedName() ) );
|
||||||
final Column column = (Column) selectable;
|
if ( existingColumn == null ) {
|
||||||
final ColumnInformation existingColumn = tableInformation.getColumn( Identifier.toIdentifier( column.getQuotedName() ) );
|
throw new SchemaManagementException(
|
||||||
if ( existingColumn == null ) {
|
String.format(
|
||||||
throw new SchemaManagementException(
|
"Schema-validation: missing column [%s] in table [%s]",
|
||||||
String.format(
|
column.getName(),
|
||||||
"Schema-validation: missing column [%s] in table [%s]",
|
table.getQualifiedTableName()
|
||||||
column.getName(),
|
)
|
||||||
table.getQualifiedTableName()
|
);
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
validateColumnType( table, column, existingColumn, metadata, options, dialect );
|
|
||||||
}
|
}
|
||||||
|
validateColumnType( table, column, existingColumn, metadata, options, dialect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +162,8 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
|
||||||
ExecutionOptions options,
|
ExecutionOptions options,
|
||||||
Dialect dialect) {
|
Dialect dialect) {
|
||||||
boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode( metadata ), columnInformation.getTypeCode() )
|
boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode( metadata ), columnInformation.getTypeCode() )
|
||||||
|| column.getSqlType( dialect, metadata ).toLowerCase(Locale.ROOT).startsWith( columnInformation.getTypeName().toLowerCase(Locale.ROOT) );
|
|| column.getSqlType( dialect, metadata ).toLowerCase(Locale.ROOT)
|
||||||
|
.startsWith( columnInformation.getTypeName().toLowerCase(Locale.ROOT) );
|
||||||
if ( !typesMatch ) {
|
if ( !typesMatch ) {
|
||||||
throw new SchemaManagementException(
|
throw new SchemaManagementException(
|
||||||
String.format(
|
String.format(
|
||||||
|
@ -186,14 +178,6 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the old Hibernate check...
|
|
||||||
//
|
|
||||||
// but I think a better check involves checks against type code and then the type code family, not
|
|
||||||
// just the type name.
|
|
||||||
//
|
|
||||||
// See org.hibernate.type.descriptor.sql.JdbcTypeFamilyInformation
|
|
||||||
// todo : this ^^
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void validateSequence(Sequence sequence, SequenceInformation sequenceInformation) {
|
protected void validateSequence(Sequence sequence, SequenceInformation sequenceInformation) {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.hibernate.orm.test.length;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@SessionFactory
|
||||||
|
@DomainModel(annotatedClasses = WithLongStrings.class)
|
||||||
|
public class LengthTest {
|
||||||
|
@Test
|
||||||
|
public void testLength(SessionFactoryScope scope) {
|
||||||
|
WithLongStrings strings = new WithLongStrings();
|
||||||
|
strings.long16 = "hello world ".repeat(2700);
|
||||||
|
strings.long32 = "hello world ".repeat(20000);
|
||||||
|
scope.inTransaction(s->s.persist(strings));
|
||||||
|
scope.inTransaction(s-> {
|
||||||
|
WithLongStrings strs = s.find(WithLongStrings.class, strings.id);
|
||||||
|
assertEquals(strs.long16, strings.long16);
|
||||||
|
assertEquals(strs.long32, strings.long32);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.hibernate.orm.test.length;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
import static org.hibernate.Length.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class WithLongStrings {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
public int id;
|
||||||
|
|
||||||
|
@Column(length = LONG16)
|
||||||
|
public String long16;
|
||||||
|
|
||||||
|
@Column(length = LONG32)
|
||||||
|
public String long32;
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
<generator class="increment"/>
|
<generator class="increment"/>
|
||||||
</id>
|
</id>
|
||||||
|
|
||||||
<property name="longByteArray" column="LONG_BYTE_ARRAY" type="image" length="15000"/>
|
<property name="longByteArray" column="LONG_BYTE_ARRAY" type="image" length="17000"/>
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
</hibernate-mapping>
|
</hibernate-mapping>
|
|
@ -53,7 +53,7 @@ public class GeneratedUuidTests {
|
||||||
|
|
||||||
// then changing
|
// then changing
|
||||||
final GeneratedUuidEntity merged = scope.fromTransaction( (session) -> {
|
final GeneratedUuidEntity merged = scope.fromTransaction( (session) -> {
|
||||||
return (GeneratedUuidEntity) session.merge( created );
|
return session.merge( created );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
assertThat( merged ).isNotNull();
|
assertThat( merged ).isNotNull();
|
||||||
|
|
|
@ -53,7 +53,8 @@ public class LongVarcharValidationTest implements ExecutionOptions {
|
||||||
@Parameterized.Parameters
|
@Parameterized.Parameters
|
||||||
public static Collection<String> parameters() {
|
public static Collection<String> parameters() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new String[] {JdbcMetadaAccessStrategy.GROUPED.toString(), JdbcMetadaAccessStrategy.INDIVIDUALLY.toString()}
|
JdbcMetadaAccessStrategy.GROUPED.toString(),
|
||||||
|
JdbcMetadaAccessStrategy.INDIVIDUALLY.toString()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,10 +52,8 @@ public class NumericValidationTest implements ExecutionOptions {
|
||||||
@Parameterized.Parameters
|
@Parameterized.Parameters
|
||||||
public static Collection<String> parameters() {
|
public static Collection<String> parameters() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new String[] {
|
JdbcMetadaAccessStrategy.GROUPED.toString(),
|
||||||
JdbcMetadaAccessStrategy.GROUPED.toString(),
|
JdbcMetadaAccessStrategy.INDIVIDUALLY.toString()
|
||||||
JdbcMetadaAccessStrategy.INDIVIDUALLY.toString()
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue