warning cleanups in Dialects
This commit is contained in:
parent
47f9bcfb24
commit
fc9229e9f4
|
@ -60,36 +60,25 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
|
|||
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 ( sqlTypeCode ) {
|
||||
case BOOLEAN:
|
||||
return "bit";
|
||||
return switch (sqlTypeCode) {
|
||||
case BOOLEAN -> "bit";
|
||||
|
||||
case TINYINT:
|
||||
//'tinyint' is an unsigned type in Sybase and
|
||||
//SQL Server, holding values in the range 0-255
|
||||
//see HHH-6779
|
||||
return "smallint";
|
||||
case INTEGER:
|
||||
//it's called 'int' not 'integer'
|
||||
return "int";
|
||||
// 'tinyint' is an unsigned type in Sybase and
|
||||
// SQL Server, holding values in the range 0-255
|
||||
// see HHH-6779
|
||||
case TINYINT -> "smallint";
|
||||
|
||||
case DATE:
|
||||
case TIME:
|
||||
case TIMESTAMP:
|
||||
case TIME_WITH_TIMEZONE:
|
||||
case TIMESTAMP_WITH_TIMEZONE:
|
||||
return "datetime";
|
||||
//it's called 'int' not 'integer'
|
||||
case INTEGER -> "int";
|
||||
|
||||
case BLOB:
|
||||
return "image";
|
||||
case CLOB:
|
||||
return "text";
|
||||
case NCLOB:
|
||||
return "ntext";
|
||||
case DATE, TIME, TIMESTAMP, TIME_WITH_TIMEZONE, TIMESTAMP_WITH_TIMEZONE -> "datetime";
|
||||
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
case BLOB -> "image";
|
||||
case CLOB -> "text";
|
||||
case NCLOB -> "ntext";
|
||||
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,20 +162,17 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
public static String replaceLtrimRtrim(TrimSpec specification, boolean isWhitespace) {
|
||||
switch ( specification ) {
|
||||
case LEADING:
|
||||
return isWhitespace
|
||||
? "ltrim(?1)"
|
||||
: "substring(?1,patindex('%[^'+?2+']%',?1),len(?1+'x')-1-patindex('%[^'+?2+']%',?1)+1)";
|
||||
case TRAILING:
|
||||
return isWhitespace
|
||||
? "rtrim(?1)"
|
||||
: "substring(?1,1,len(?1+'x')-1-patindex('%[^'+?2+']%',reverse(?1))+1)";
|
||||
default:
|
||||
return isWhitespace
|
||||
? "ltrim(rtrim(?1))"
|
||||
: "substring(?1,patindex('%[^'+?2+']%',?1),len(?1+'x')-1-patindex('%[^'+?2+']%',?1)-patindex('%[^'+?2+']%',reverse(?1))+2)";
|
||||
}
|
||||
return switch (specification) {
|
||||
case LEADING -> isWhitespace
|
||||
? "ltrim(?1)"
|
||||
: "substring(?1,patindex('%[^'+?2+']%',?1),len(?1+'x')-1-patindex('%[^'+?2+']%',?1)+1)";
|
||||
case TRAILING -> isWhitespace
|
||||
? "rtrim(?1)"
|
||||
: "substring(?1,1,len(?1+'x')-1-patindex('%[^'+?2+']%',reverse(?1))+1)";
|
||||
default -> isWhitespace
|
||||
? "ltrim(rtrim(?1))"
|
||||
: "substring(?1,patindex('%[^'+?2+']%',?1),len(?1+'x')-1-patindex('%[^'+?2+']%',?1)-patindex('%[^'+?2+']%',reverse(?1))+2)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.query.SemanticException;
|
||||
|
@ -80,8 +79,10 @@ import org.jboss.logging.Logger;
|
|||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static java.lang.Integer.parseInt;
|
||||
import static org.hibernate.cfg.DialectSpecificSettings.COCKROACH_VERSION_STRING;
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.EPOCH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
|
||||
|
@ -165,7 +166,7 @@ public class CockroachDialect extends Dialect {
|
|||
protected static DatabaseVersion fetchDataBaseVersion(DialectResolutionInfo info) {
|
||||
String versionString = null;
|
||||
if ( info.getDatabaseMetadata() != null ) {
|
||||
try (java.sql.Statement s = info.getDatabaseMetadata().getConnection().createStatement()) {
|
||||
try ( java.sql.Statement s = info.getDatabaseMetadata().getConnection().createStatement() ) {
|
||||
final ResultSet rs = s.executeQuery( "SELECT version()" );
|
||||
if ( rs.next() ) {
|
||||
versionString = rs.getString( 1 );
|
||||
|
@ -185,14 +186,13 @@ public class CockroachDialect extends Dialect {
|
|||
public static DatabaseVersion parseVersion( String versionString ) {
|
||||
DatabaseVersion databaseVersion = null;
|
||||
// What the DB select returns is similar to "CockroachDB CCL v21.2.10 (x86_64-unknown-linux-gnu, built 2022/05/02 17:38:58, go1.16.6)"
|
||||
Matcher m = CRDB_VERSION_PATTERN.matcher( versionString == null ? "" : versionString );
|
||||
if ( m.find() ) {
|
||||
String[] versionParts = StringHelper.split( ".", m.group().substring( 1 ) );
|
||||
final Matcher matcher = CRDB_VERSION_PATTERN.matcher( versionString == null ? "" : versionString );
|
||||
if ( matcher.find() ) {
|
||||
final String[] versionParts = StringHelper.split( ".", matcher.group().substring( 1 ) );
|
||||
// if we got to this point, there is at least a major version, so no need to check [].length > 0
|
||||
int majorVersion = Integer.parseInt( versionParts[0] );
|
||||
int minorVersion = versionParts.length > 1 ? Integer.parseInt( versionParts[1] ) : 0;
|
||||
int microVersion = versionParts.length > 2 ? Integer.parseInt( versionParts[2] ) : 0;
|
||||
|
||||
int majorVersion = parseInt( versionParts[0] );
|
||||
int minorVersion = versionParts.length > 1 ? parseInt( versionParts[1] ) : 0;
|
||||
int microVersion = versionParts.length > 2 ? parseInt( versionParts[2] ) : 0;
|
||||
databaseVersion= new SimpleDatabaseVersion( majorVersion, minorVersion, microVersion);
|
||||
}
|
||||
if ( databaseVersion == null ) {
|
||||
|
@ -213,59 +213,35 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case TINYINT:
|
||||
return "smallint"; //no tinyint
|
||||
case INTEGER:
|
||||
return "int4";
|
||||
|
||||
case NCHAR:
|
||||
return columnType( CHAR );
|
||||
case NVARCHAR:
|
||||
return columnType( VARCHAR );
|
||||
|
||||
case NCLOB:
|
||||
case CLOB:
|
||||
return "string";
|
||||
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case BLOB:
|
||||
return "bytes";
|
||||
|
||||
// We do not use the time with timezone type because PG deprecated it and it lacks certain operations like subtraction
|
||||
// case TIME_UTC:
|
||||
// return columnType( TIME_WITH_TIMEZONE );
|
||||
|
||||
case TIMESTAMP_UTC:
|
||||
return columnType( TIMESTAMP_WITH_TIMEZONE );
|
||||
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
return switch (sqlTypeCode) {
|
||||
case TINYINT -> "smallint"; // no tinyint
|
||||
case INTEGER -> "int4";
|
||||
case NCHAR -> columnType( CHAR );
|
||||
case NVARCHAR -> columnType( VARCHAR );
|
||||
case NCLOB, CLOB -> "string";
|
||||
case BINARY, VARBINARY, BLOB -> "bytes";
|
||||
// We do not use the time with timezone type because PG
|
||||
// deprecated it and it lacks certain operations like
|
||||
// subtraction
|
||||
// case TIME_UTC -> columnType( TIME_WITH_TIMEZONE );
|
||||
case TIMESTAMP_UTC -> columnType( TIMESTAMP_WITH_TIMEZONE );
|
||||
default -> super.columnType(sqlTypeCode);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String castType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case CHAR:
|
||||
case NCHAR:
|
||||
case VARCHAR:
|
||||
case NVARCHAR:
|
||||
case LONG32VARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
return "string";
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
return "bytes";
|
||||
}
|
||||
return super.castType( sqlTypeCode );
|
||||
return switch (sqlTypeCode) {
|
||||
case CHAR, NCHAR, VARCHAR, NVARCHAR, LONG32VARCHAR, LONG32NVARCHAR -> "string";
|
||||
case BINARY, VARBINARY, LONG32VARBINARY -> "bytes";
|
||||
default -> super.castType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.registerColumnTypes( typeContributions, serviceRegistry );
|
||||
|
||||
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
|
||||
|
||||
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
|
||||
|
@ -344,22 +320,15 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected Integer resolveSqlTypeCode(String columnTypeName, TypeConfiguration typeConfiguration) {
|
||||
switch ( columnTypeName ) {
|
||||
case "bool":
|
||||
return Types.BOOLEAN;
|
||||
case "float4":
|
||||
// Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
return Types.REAL;
|
||||
case "float8":
|
||||
return Types.DOUBLE;
|
||||
case "int2":
|
||||
return Types.SMALLINT;
|
||||
case "int4":
|
||||
return Types.INTEGER;
|
||||
case "int8":
|
||||
return Types.BIGINT;
|
||||
}
|
||||
return super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
return switch (columnTypeName) {
|
||||
case "bool" -> Types.BOOLEAN;
|
||||
case "float4" -> Types.REAL; // Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
case "float8" -> Types.DOUBLE;
|
||||
case "int2" -> Types.SMALLINT;
|
||||
case "int4" -> Types.INTEGER;
|
||||
case "int8" -> Types.BIGINT;
|
||||
default -> super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -499,10 +468,7 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
new PostgreSQLTruncFunction(
|
||||
true,
|
||||
functionContributions.getTypeConfiguration()
|
||||
)
|
||||
new PostgreSQLTruncFunction( true, functionContributions.getTypeConfiguration() )
|
||||
);
|
||||
functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" );
|
||||
}
|
||||
|
@ -609,7 +575,8 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public boolean supportsNullPrecedence() {
|
||||
// Not yet implemented: https://www.cockroachlabs.com/docs/v20.2/null-handling.html#nulls-and-sorting
|
||||
// Not yet implemented:
|
||||
// https://www.cockroachlabs.com/docs/v20.2/null-handling.html#nulls-and-sorting
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -684,6 +651,7 @@ public class CockroachDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -721,7 +689,12 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "date '" );
|
||||
|
@ -747,6 +720,7 @@ public class CockroachDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -778,22 +752,20 @@ public class CockroachDialect extends Dialect {
|
|||
*/
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_WEEK:
|
||||
return "(" + super.extractPattern(unit) + "+1)";
|
||||
default:
|
||||
return super.extractPattern(unit);
|
||||
}
|
||||
return switch (unit) {
|
||||
case DAY_OF_WEEK -> "(" + super.extractPattern( unit ) + "+1)";
|
||||
default -> super.extractPattern( unit );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_MONTH: return "day";
|
||||
case DAY_OF_YEAR: return "dayofyear";
|
||||
case DAY_OF_WEEK: return "dayofweek";
|
||||
default: return super.translateExtractField( unit );
|
||||
}
|
||||
return switch (unit) {
|
||||
case DAY_OF_MONTH -> "day";
|
||||
case DAY_OF_YEAR -> "dayofyear";
|
||||
case DAY_OF_WEEK -> "dayofweek";
|
||||
default -> super.translateExtractField( unit );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -805,7 +777,7 @@ public class CockroachDialect extends Dialect {
|
|||
return 1_000; //microseconds
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
return intervalType != null
|
||||
? "(?2+?3)"
|
||||
|
@ -813,21 +785,16 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
private static String intervalPattern(TemporalUnit unit) {
|
||||
switch (unit) {
|
||||
case NATIVE:
|
||||
return "(?2)*interval '1 microsecond'";
|
||||
case NANOSECOND:
|
||||
return "(?2)/1e3*interval '1 microsecond'";
|
||||
case QUARTER: //quarter is not supported in interval literals
|
||||
return "(?2)*interval '3 month'";
|
||||
case WEEK: //week is not supported in interval literals
|
||||
return "(?2)*interval '7 day'";
|
||||
default:
|
||||
return "(?2)*interval '1 " + unit + "'";
|
||||
}
|
||||
return switch (unit) {
|
||||
case NATIVE -> "(?2)*interval '1 microsecond'";
|
||||
case NANOSECOND -> "(?2)/1e3*interval '1 microsecond'";
|
||||
case QUARTER -> "(?2)*interval '3 month'"; // quarter is not supported in interval literals
|
||||
case WEEK -> "(?2)*interval '7 day'"; // week is not supported in interval literals
|
||||
default -> "(?2)*interval '1 " + unit + "'";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
if ( unit == null ) {
|
||||
return "(?3-?2)";
|
||||
|
@ -836,46 +803,33 @@ public class CockroachDialect extends Dialect {
|
|||
// special case: subtraction of two dates
|
||||
// results in an integer number of days
|
||||
// instead of an INTERVAL
|
||||
switch ( unit ) {
|
||||
case YEAR:
|
||||
case MONTH:
|
||||
case QUARTER:
|
||||
return switch (unit) {
|
||||
case YEAR, MONTH, QUARTER ->
|
||||
// age only supports timestamptz, so we have to cast the date expressions
|
||||
return "extract(" + translateDurationField( unit ) + " from age(cast(?3 as timestamptz),cast(?2 as timestamptz)))";
|
||||
default:
|
||||
return "(?3-?2)" + DAY.conversionFactor( unit, this );
|
||||
}
|
||||
"extract(" + translateDurationField( unit )
|
||||
+ " from age(cast(?3 as timestamptz),cast(?2 as timestamptz)))";
|
||||
default -> "(?3-?2)" + DAY.conversionFactor( unit, this );
|
||||
};
|
||||
}
|
||||
else {
|
||||
switch (unit) {
|
||||
case YEAR:
|
||||
return "extract(year from ?3-?2)";
|
||||
case QUARTER:
|
||||
return "(extract(year from ?3-?2)*4+extract(month from ?3-?2)//3)";
|
||||
case MONTH:
|
||||
return "(extract(year from ?3-?2)*12+extract(month from ?3-?2))";
|
||||
case WEEK: //week is not supported by extract() when the argument is a duration
|
||||
return "(extract(day from ?3-?2)/7)";
|
||||
case DAY:
|
||||
return "extract(day from ?3-?2)";
|
||||
return switch (unit) {
|
||||
case YEAR -> "extract(year from ?3-?2)";
|
||||
case QUARTER -> "(extract(year from ?3-?2)*4+extract(month from ?3-?2)//3)";
|
||||
case MONTH -> "(extract(year from ?3-?2)*12+extract(month from ?3-?2))";
|
||||
case WEEK -> "(extract(day from ?3-?2)/7)"; // week is not supported by extract() when the argument is a duration
|
||||
case DAY -> "extract(day from ?3-?2)";
|
||||
//in order to avoid multiple calls to extract(),
|
||||
//we use extract(epoch from x - y) * factor for
|
||||
//all the following units:
|
||||
|
||||
// Note that CockroachDB also has an extract_duration function which returns an int,
|
||||
// but we don't use that here because it is deprecated since v20.
|
||||
// We need to use round() instead of cast(... as int) because extract epoch returns
|
||||
// float8 which can cause loss-of-precision in some cases
|
||||
// https://github.com/cockroachdb/cockroach/issues/72523
|
||||
case HOUR:
|
||||
case MINUTE:
|
||||
case SECOND:
|
||||
case NANOSECOND:
|
||||
case NATIVE:
|
||||
return "round(extract(epoch from ?3-?2)" + EPOCH.conversionFactor( unit, this ) + ")::int";
|
||||
default:
|
||||
throw new SemanticException( "Unrecognized field: " + unit );
|
||||
}
|
||||
case HOUR, MINUTE, SECOND, NANOSECOND, NATIVE ->
|
||||
"round(extract(epoch from ?3-?2)" + EPOCH.conversionFactor( unit, this ) + ")::int";
|
||||
default -> throw new SemanticException( "Unrecognized field: " + unit );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +837,7 @@ public class CockroachDialect extends Dialect {
|
|||
public String translateDurationField(TemporalUnit unit) {
|
||||
return unit==NATIVE
|
||||
? "microsecond"
|
||||
: super.translateDurationField(unit);
|
||||
: super.translateDurationField( unit );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -908,14 +862,12 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases, LockOptions lockOptions) {
|
||||
/*
|
||||
* Parent's implementation for (aliases, lockOptions) ignores aliases.
|
||||
*/
|
||||
// Parent's implementation for (aliases, lockOptions) ignores aliases.
|
||||
if ( aliases.isEmpty() ) {
|
||||
LockMode lockMode = lockOptions.getLockMode();
|
||||
final LockMode lockMode = lockOptions.getLockMode();
|
||||
for ( Map.Entry<String, LockMode> entry : lockOptions.getAliasSpecificLocks() ) {
|
||||
// seek the highest lock mode
|
||||
if ( entry.getValue().greaterThan(lockMode) ) {
|
||||
if ( entry.getValue().greaterThan( lockMode ) ) {
|
||||
aliases = entry.getKey();
|
||||
}
|
||||
}
|
||||
|
@ -924,38 +876,21 @@ public class CockroachDialect extends Dialect {
|
|||
if (lockMode == null ) {
|
||||
lockMode = lockOptions.getLockMode();
|
||||
}
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_READ: {
|
||||
return getReadLockString( aliases, lockOptions.getTimeOut() );
|
||||
}
|
||||
case PESSIMISTIC_WRITE: {
|
||||
return getWriteLockString( aliases, lockOptions.getTimeOut() );
|
||||
}
|
||||
case UPGRADE_NOWAIT:
|
||||
case PESSIMISTIC_FORCE_INCREMENT: {
|
||||
return getForUpdateNowaitString(aliases);
|
||||
}
|
||||
case UPGRADE_SKIPLOCKED: {
|
||||
return getForUpdateSkipLockedString(aliases);
|
||||
}
|
||||
default: {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_READ -> getReadLockString( aliases, lockOptions.getTimeOut() );
|
||||
case PESSIMISTIC_WRITE -> getWriteLockString( aliases, lockOptions.getTimeOut() );
|
||||
case UPGRADE_NOWAIT, PESSIMISTIC_FORCE_INCREMENT -> getForUpdateNowaitString( aliases );
|
||||
case UPGRADE_SKIPLOCKED -> getForUpdateSkipLockedString( aliases );
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
private String withTimeout(String lockString, int timeout) {
|
||||
switch (timeout) {
|
||||
case LockOptions.NO_WAIT: {
|
||||
return supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
}
|
||||
case LockOptions.SKIP_LOCKED: {
|
||||
return supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
}
|
||||
default: {
|
||||
return lockString;
|
||||
}
|
||||
}
|
||||
return switch (timeout) {
|
||||
case LockOptions.NO_WAIT -> supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case LockOptions.SKIP_LOCKED -> supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
default -> lockString;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -970,12 +905,12 @@ public class CockroachDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
return withTimeout(" for share", timeout );
|
||||
return withTimeout( " for share", timeout );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(String aliases, int timeout) {
|
||||
return withTimeout(" for share of " + aliases, timeout );
|
||||
return withTimeout( " for share of " + aliases, timeout );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1070,15 +1005,15 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
|
||||
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData databaseMetaData)
|
||||
throws SQLException {
|
||||
|
||||
if ( dbMetaData == null ) {
|
||||
if ( databaseMetaData == null ) {
|
||||
builder.setUnquotedCaseStrategy( IdentifierCaseStrategy.LOWER );
|
||||
builder.setQuotedCaseStrategy( IdentifierCaseStrategy.MIXED );
|
||||
}
|
||||
|
||||
return super.buildIdentifierHelper( builder, dbMetaData );
|
||||
return super.buildIdentifierHelper( builder, databaseMetaData );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1092,52 +1027,42 @@ public class CockroachDialect extends Dialect {
|
|||
*/
|
||||
private static final ViolatedConstraintNameExtractor EXTRACTOR =
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle -> {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqle );
|
||||
final String sqlState = extractSqlState( sqle );
|
||||
if ( sqlState == null ) {
|
||||
return null;
|
||||
}
|
||||
switch ( Integer.parseInt( sqlState ) ) {
|
||||
return switch ( parseInt( sqlState ) ) {
|
||||
// CHECK VIOLATION
|
||||
case 23514:
|
||||
return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
|
||||
case 23514 -> extractUsingTemplate( "violates check constraint \"", "\"", sqle.getMessage() );
|
||||
// UNIQUE VIOLATION
|
||||
case 23505:
|
||||
return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
|
||||
case 23505 -> extractUsingTemplate(" violates unique constraint \"", "\"", sqle.getMessage() );
|
||||
// FOREIGN KEY VIOLATION
|
||||
case 23503:
|
||||
return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
|
||||
case 23503 -> extractUsingTemplate( "violates foreign key constraint \"", "\"", sqle.getMessage() );
|
||||
// NOT NULL VIOLATION
|
||||
case 23502:
|
||||
return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
|
||||
case 23502 -> extractUsingTemplate( "null value in column \"", "\" violates not-null constraint", sqle.getMessage() );
|
||||
// TODO: RESTRICT VIOLATION
|
||||
case 23001:
|
||||
return null;
|
||||
case 23001 -> null;
|
||||
// ALL OTHER
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
} );
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final String sqlState = extractSqlState( sqlException );
|
||||
if ( sqlState == null ) {
|
||||
return null;
|
||||
}
|
||||
switch ( sqlState ) {
|
||||
case "40P01":
|
||||
// DEADLOCK DETECTED
|
||||
return new LockAcquisitionException( message, sqlException, sql);
|
||||
case "55P03":
|
||||
// LOCK NOT AVAILABLE
|
||||
return new PessimisticLockException( message, sqlException, sql);
|
||||
case "57014":
|
||||
return new QueryTimeoutException( message, sqlException, sql );
|
||||
default:
|
||||
// returning null allows other delegates to operate
|
||||
return null;
|
||||
}
|
||||
return switch (sqlState) {
|
||||
// DEADLOCK DETECTED
|
||||
case "40P01" -> new LockAcquisitionException( message, sqlException, sql );
|
||||
// LOCK NOT AVAILABLE
|
||||
case "55P03" -> new PessimisticLockException( message, sqlException, sql );
|
||||
case "57014" -> new QueryTimeoutException( message, sqlException, sql );
|
||||
// returning null allows other delegates to operate
|
||||
default -> null;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ import org.hibernate.exception.LockTimeoutException;
|
|||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -104,6 +103,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
import static org.hibernate.type.SqlTypes.BLOB;
|
||||
import static org.hibernate.type.SqlTypes.BOOLEAN;
|
||||
|
@ -193,36 +193,39 @@ public class DB2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case BOOLEAN:
|
||||
return 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 columnType( DECIMAL );
|
||||
case BLOB:
|
||||
return "blob";
|
||||
case CLOB:
|
||||
return "clob";
|
||||
case TIMESTAMP_WITH_TIMEZONE:
|
||||
return "timestamp($p)";
|
||||
case TIME:
|
||||
case TIME_WITH_TIMEZONE:
|
||||
return "time";
|
||||
case BINARY:
|
||||
getDB2Version().isBefore( 11 )
|
||||
? "smallint"
|
||||
: super.columnType( sqlTypeCode );
|
||||
|
||||
case TINYINT -> "smallint"; // no tinyint
|
||||
|
||||
// HHH-12827: map them both to the same type to avoid problems with schema update
|
||||
// Note that 31 is the maximum precision DB2 supports
|
||||
case NUMERIC -> columnType( DECIMAL );
|
||||
|
||||
case BLOB -> "blob";
|
||||
case CLOB -> "clob";
|
||||
|
||||
case TIMESTAMP_WITH_TIMEZONE -> "timestamp($p)";
|
||||
case TIME, TIME_WITH_TIMEZONE -> "time";
|
||||
|
||||
case BINARY ->
|
||||
// should use 'binary' since version 11
|
||||
return getDB2Version().isBefore( 11 ) ? "char($l) for bit data" : super.columnType( sqlTypeCode );
|
||||
case VARBINARY:
|
||||
getDB2Version().isBefore( 11 )
|
||||
? "char($l) for bit data"
|
||||
: super.columnType( sqlTypeCode );
|
||||
case VARBINARY ->
|
||||
// should use 'varbinary' since version 11
|
||||
return getDB2Version().isBefore( 11 ) ? "varchar($l) for bit data" : super.columnType( sqlTypeCode );
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
getDB2Version().isBefore( 11 )
|
||||
? "varchar($l) for bit data"
|
||||
: super.columnType( sqlTypeCode );
|
||||
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -433,7 +436,7 @@ public class DB2Dialect extends Dialect {
|
|||
return 1_000_000_000; //seconds
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
if ( getDB2Version().isBefore( 11 ) ) {
|
||||
return timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
|
||||
|
@ -446,28 +449,16 @@ public class DB2Dialect extends Dialect {
|
|||
toExpression = "?3";
|
||||
}
|
||||
else {
|
||||
switch ( fromTemporalType ) {
|
||||
case DATE:
|
||||
fromExpression = "cast(?2 as timestamp)";
|
||||
break;
|
||||
case TIME:
|
||||
fromExpression = "timestamp('1970-01-01',?2)";
|
||||
break;
|
||||
default:
|
||||
fromExpression = "?2";
|
||||
break;
|
||||
}
|
||||
switch ( toTemporalType ) {
|
||||
case DATE:
|
||||
toExpression = "cast(?3 as timestamp)";
|
||||
break;
|
||||
case TIME:
|
||||
toExpression = "timestamp('1970-01-01',?3)";
|
||||
break;
|
||||
default:
|
||||
toExpression = "?3";
|
||||
break;
|
||||
}
|
||||
fromExpression = switch (fromTemporalType) {
|
||||
case DATE -> "cast(?2 as timestamp)";
|
||||
case TIME -> "timestamp('1970-01-01',?2)";
|
||||
default -> "?2";
|
||||
};
|
||||
toExpression = switch (toTemporalType) {
|
||||
case DATE -> "cast(?3 as timestamp)";
|
||||
case TIME -> "timestamp('1970-01-01',?3)";
|
||||
default -> "?3";
|
||||
};
|
||||
}
|
||||
switch ( unit ) {
|
||||
case NATIVE:
|
||||
|
@ -521,6 +512,7 @@ public class DB2Dialect extends Dialect {
|
|||
return pattern.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static String timestampdiffPatternV10(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
final boolean isTime = fromTemporalType == TemporalType.TIME || toTemporalType == TemporalType.TIME;
|
||||
final String fromExpression;
|
||||
|
@ -611,7 +603,7 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
final StringBuilder pattern = new StringBuilder();
|
||||
final String timestampExpression;
|
||||
|
@ -658,6 +650,7 @@ public class DB2Dialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -682,7 +675,12 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "date '" );
|
||||
|
@ -708,6 +706,7 @@ public class DB2Dialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -825,25 +824,13 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
public static String selectNullString(int sqlType) {
|
||||
String literal;
|
||||
switch ( sqlType ) {
|
||||
case Types.VARCHAR:
|
||||
case Types.CHAR:
|
||||
literal = "''";
|
||||
break;
|
||||
case Types.DATE:
|
||||
literal = "'2000-1-1'";
|
||||
break;
|
||||
case Types.TIME:
|
||||
literal = "'00:00:00'";
|
||||
break;
|
||||
case Types.TIMESTAMP:
|
||||
case Types.TIMESTAMP_WITH_TIMEZONE:
|
||||
literal = "'2000-1-1 00:00:00'";
|
||||
break;
|
||||
default:
|
||||
literal = "0";
|
||||
}
|
||||
final String literal = switch (sqlType) {
|
||||
case Types.VARCHAR, Types.CHAR -> "''";
|
||||
case Types.DATE -> "'2000-1-1'";
|
||||
case Types.TIME -> "'00:00:00'";
|
||||
case Types.TIMESTAMP, Types.TIMESTAMP_WITH_TIMEZONE -> "'2000-1-1 00:00:00'";
|
||||
default -> "0";
|
||||
};
|
||||
return "nullif(" + literal + "," + literal + ')';
|
||||
}
|
||||
|
||||
|
@ -1073,34 +1060,25 @@ public class DB2Dialect extends Dialect {
|
|||
@Override
|
||||
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
|
||||
return new TemplatedViolatedConstraintNameExtractor(
|
||||
sqle -> {
|
||||
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
|
||||
case -803:
|
||||
return extractUsingTemplate( "SQLERRMC=1;", ",", sqle.getMessage() );
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
sqle -> switch ( extractErrorCode( sqle ) ) {
|
||||
case -803 -> extractUsingTemplate( "SQLERRMC=1;", ",", sqle.getMessage() );
|
||||
default -> null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
switch ( errorCode ) {
|
||||
case -952:
|
||||
return new LockTimeoutException( message, sqlException, sql );
|
||||
case -803:
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
}
|
||||
return null;
|
||||
return (sqlException, message, sql) -> switch ( extractErrorCode( sqlException ) ) {
|
||||
case -952 -> new LockTimeoutException( message, sqlException, sql );
|
||||
case -803 -> new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1197,13 +1175,13 @@ public class DB2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
return switch (unit) {
|
||||
//WEEK means the ISO week number on DB2
|
||||
case DAY_OF_MONTH: return "day";
|
||||
case DAY_OF_YEAR: return "doy";
|
||||
case DAY_OF_WEEK: return "dow";
|
||||
default: return super.translateExtractField( unit );
|
||||
}
|
||||
case DAY_OF_MONTH -> "day";
|
||||
case DAY_OF_YEAR -> "doy";
|
||||
case DAY_OF_WEEK -> "dow";
|
||||
default -> super.translateExtractField( unit );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1220,7 +1198,8 @@ public class DB2Dialect extends Dialect {
|
|||
public String extractPattern(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case WEEK:
|
||||
// Not sure why, but `extract(week from '2019-05-27')` wrongly returns 21 and week_iso behaves correct
|
||||
// Not sure why, but `extract(week from '2019-05-27')`
|
||||
// wrongly returns 21 and week_iso behaves correct
|
||||
return "week_iso(?2)";
|
||||
case DAY_OF_YEAR:
|
||||
return "dayofyear(?2)";
|
||||
|
|
|
@ -457,17 +457,10 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
}
|
||||
|
||||
protected boolean isLob(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case LONG32VARBINARY:
|
||||
case LONG32VARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
case BLOB:
|
||||
case CLOB:
|
||||
case NCLOB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return switch (sqlTypeCode) {
|
||||
case LONG32VARBINARY, LONG32VARCHAR, LONG32NVARCHAR, BLOB, CLOB, NCLOB -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private DdlTypeImpl simpleSqlType(int sqlTypeCode) {
|
||||
|
@ -542,96 +535,71 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* @see SqlTypes
|
||||
*/
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case ROWID:
|
||||
return "rowid";
|
||||
return switch (sqlTypeCode) {
|
||||
case ROWID -> "rowid";
|
||||
|
||||
case BOOLEAN:
|
||||
return "boolean";
|
||||
case BOOLEAN -> "boolean";
|
||||
|
||||
case TINYINT:
|
||||
return "tinyint";
|
||||
case SMALLINT:
|
||||
return "smallint";
|
||||
case INTEGER:
|
||||
return "integer";
|
||||
case BIGINT:
|
||||
return "bigint";
|
||||
case TINYINT -> "tinyint";
|
||||
case SMALLINT -> "smallint";
|
||||
case INTEGER -> "integer";
|
||||
case BIGINT -> "bigint";
|
||||
|
||||
case FLOAT:
|
||||
case FLOAT ->
|
||||
// this is the floating point type we prefer!
|
||||
return "float($p)";
|
||||
case REAL:
|
||||
"float($p)";
|
||||
case REAL ->
|
||||
// this type has very unclear semantics in ANSI SQL,
|
||||
// so we avoid it and prefer float with an explicit
|
||||
// precision
|
||||
return "real";
|
||||
case DOUBLE:
|
||||
"real";
|
||||
case DOUBLE ->
|
||||
// this is just a more verbose way to write float(19)
|
||||
return "double precision";
|
||||
"double precision";
|
||||
|
||||
// these are pretty much synonyms, but are considered
|
||||
// separate types by the ANSI spec, and in some dialects
|
||||
case NUMERIC:
|
||||
return "numeric($p,$s)";
|
||||
case DECIMAL:
|
||||
return "decimal($p,$s)";
|
||||
case NUMERIC -> "numeric($p,$s)";
|
||||
case DECIMAL -> "decimal($p,$s)";
|
||||
|
||||
case DATE:
|
||||
return "date";
|
||||
case TIME:
|
||||
return "time($p)";
|
||||
case TIME_WITH_TIMEZONE:
|
||||
case DATE -> "date";
|
||||
case TIME -> "time($p)";
|
||||
case TIME_WITH_TIMEZONE ->
|
||||
// type included here for completeness but note that
|
||||
// very few databases support it, and the general
|
||||
// advice is to caution against its use (for reasons,
|
||||
// check the comments in the Postgres documentation).
|
||||
return "time($p) with time zone";
|
||||
case TIMESTAMP:
|
||||
return "timestamp($p)";
|
||||
case TIMESTAMP_WITH_TIMEZONE:
|
||||
return "timestamp($p) with time zone";
|
||||
case TIME_UTC:
|
||||
return getTimeZoneSupport() == TimeZoneSupport.NATIVE
|
||||
? columnType( TIME_WITH_TIMEZONE )
|
||||
: columnType( TIME );
|
||||
case TIMESTAMP_UTC:
|
||||
return getTimeZoneSupport() == TimeZoneSupport.NATIVE
|
||||
? columnType( TIMESTAMP_WITH_TIMEZONE )
|
||||
: columnType( TIMESTAMP );
|
||||
"time($p) with time zone";
|
||||
case TIMESTAMP -> "timestamp($p)";
|
||||
case TIMESTAMP_WITH_TIMEZONE -> "timestamp($p) with time zone";
|
||||
case TIME_UTC ->
|
||||
getTimeZoneSupport() == TimeZoneSupport.NATIVE
|
||||
? columnType( TIME_WITH_TIMEZONE )
|
||||
: columnType( TIME );
|
||||
case TIMESTAMP_UTC ->
|
||||
getTimeZoneSupport() == TimeZoneSupport.NATIVE
|
||||
? columnType( TIMESTAMP_WITH_TIMEZONE )
|
||||
: columnType( TIMESTAMP );
|
||||
|
||||
case CHAR:
|
||||
return "char($l)";
|
||||
case VARCHAR:
|
||||
return "varchar($l)";
|
||||
case CLOB:
|
||||
return "clob";
|
||||
case CHAR -> "char($l)";
|
||||
case VARCHAR -> "varchar($l)";
|
||||
case CLOB -> "clob";
|
||||
|
||||
case NCHAR:
|
||||
return "nchar($l)";
|
||||
case NVARCHAR:
|
||||
return "nvarchar($l)";
|
||||
case NCLOB:
|
||||
return "nclob";
|
||||
case NCHAR -> "nchar($l)";
|
||||
case NVARCHAR -> "nvarchar($l)";
|
||||
case NCLOB -> "nclob";
|
||||
|
||||
case BINARY:
|
||||
return "binary($l)";
|
||||
case VARBINARY:
|
||||
return "varbinary($l)";
|
||||
case BLOB:
|
||||
return "blob";
|
||||
case BINARY -> "binary($l)";
|
||||
case VARBINARY -> "varbinary($l)";
|
||||
case BLOB -> "blob";
|
||||
|
||||
// by default use the LOB mappings for the "long" types
|
||||
case LONG32VARCHAR:
|
||||
return columnType( CLOB );
|
||||
case LONG32NVARCHAR:
|
||||
return columnType( NCLOB );
|
||||
case LONG32VARBINARY:
|
||||
return columnType( BLOB );
|
||||
case LONG32VARCHAR -> columnType( CLOB );
|
||||
case LONG32NVARCHAR -> columnType( NCLOB );
|
||||
case LONG32VARBINARY -> columnType( BLOB );
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException( "unknown type: " + sqlTypeCode );
|
||||
}
|
||||
default -> throw new IllegalArgumentException( "unknown type: " + sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1574,6 +1542,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* a timestamp, false if a date
|
||||
* @param toTemporalType true if the second argument is
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
throw new UnsupportedOperationException( "`" + getClass().getName() + "` does not yet support #timestampdiffPattern" );
|
||||
}
|
||||
|
@ -1588,6 +1557,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* @param temporalType The type of the temporal
|
||||
* @param intervalType The type of interval to add or null if it's not a native interval
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
throw new UnsupportedOperationException( "`" + getClass().getName() + "` does not yet support #timestampaddPattern" );
|
||||
}
|
||||
|
@ -1637,21 +1607,18 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* and migration.
|
||||
*/
|
||||
private boolean isCompatibleIntegralType(int typeCode1, int typeCode2) {
|
||||
switch (typeCode1) {
|
||||
case TINYINT:
|
||||
return typeCode2 == TINYINT
|
||||
return switch (typeCode1) {
|
||||
case TINYINT -> typeCode2 == TINYINT
|
||||
|| typeCode2 == SMALLINT
|
||||
|| typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
case SMALLINT:
|
||||
return typeCode2 == SMALLINT
|
||||
case SMALLINT -> typeCode2 == SMALLINT
|
||||
|| typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
case INTEGER:
|
||||
return typeCode2 == INTEGER
|
||||
case INTEGER -> typeCode2 == INTEGER
|
||||
|| typeCode2 == BIGINT;
|
||||
}
|
||||
return false;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean sameColumnType(int typeCode1, int typeCode2) {
|
||||
|
@ -2037,25 +2004,23 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* @since 3.2
|
||||
*/
|
||||
public LockingStrategy getLockingStrategy(EntityPersister lockable, LockMode lockMode) {
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case UPGRADE_NOWAIT:
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
case PESSIMISTIC_WRITE:
|
||||
return new PessimisticWriteSelectLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_READ:
|
||||
return new PessimisticReadSelectLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC_FORCE_INCREMENT:
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC:
|
||||
return new OptimisticLockingStrategy( lockable, lockMode );
|
||||
case READ:
|
||||
return new SelectLockingStrategy( lockable, lockMode );
|
||||
default:
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT ->
|
||||
new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case UPGRADE_NOWAIT, UPGRADE_SKIPLOCKED, PESSIMISTIC_WRITE ->
|
||||
new PessimisticWriteSelectLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_READ ->
|
||||
new PessimisticReadSelectLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC_FORCE_INCREMENT ->
|
||||
new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC ->
|
||||
new OptimisticLockingStrategy( lockable, lockMode );
|
||||
case READ ->
|
||||
new SelectLockingStrategy( lockable, lockMode );
|
||||
default ->
|
||||
// WRITE, NONE are not allowed here
|
||||
throw new IllegalArgumentException( "Unsupported lock mode" );
|
||||
}
|
||||
throw new IllegalArgumentException( "Unsupported lock mode" );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2080,24 +2045,13 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* @return The appropriate {@code for update} fragment.
|
||||
*/
|
||||
private String getForUpdateString(LockMode lockMode, int timeout) {
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_READ: {
|
||||
return getReadLockString( timeout );
|
||||
}
|
||||
case PESSIMISTIC_WRITE: {
|
||||
return getWriteLockString( timeout );
|
||||
}
|
||||
case UPGRADE_NOWAIT:
|
||||
case PESSIMISTIC_FORCE_INCREMENT: {
|
||||
return getForUpdateNowaitString();
|
||||
}
|
||||
case UPGRADE_SKIPLOCKED: {
|
||||
return getForUpdateSkipLockedString();
|
||||
}
|
||||
default: {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_READ -> getReadLockString( timeout );
|
||||
case PESSIMISTIC_WRITE -> getWriteLockString( timeout );
|
||||
case UPGRADE_NOWAIT, PESSIMISTIC_FORCE_INCREMENT -> getForUpdateNowaitString();
|
||||
case UPGRADE_SKIPLOCKED -> getForUpdateSkipLockedString();
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2657,7 +2611,6 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
/**
|
||||
* Some dialects require a not null primaryTable filter.
|
||||
* Sometimes a wildcard entry is sufficient for the like condition.
|
||||
* @return
|
||||
*/
|
||||
public String getCrossReferenceParentTableFilter(){
|
||||
return null;
|
||||
|
@ -3387,16 +3340,11 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* The command to create a temporary table.
|
||||
*/
|
||||
public String getTemporaryTableCreateCommand() {
|
||||
final TemporaryTableKind kind = getSupportedTemporaryTableKind();
|
||||
switch ( kind ) {
|
||||
case PERSISTENT:
|
||||
return "create table";
|
||||
case LOCAL:
|
||||
return "create local temporary table";
|
||||
case GLOBAL:
|
||||
return "create global temporary table";
|
||||
}
|
||||
throw new UnsupportedOperationException( "Unsupported kind: " + kind );
|
||||
return switch ( getSupportedTemporaryTableKind() ) {
|
||||
case PERSISTENT -> "create table";
|
||||
case LOCAL -> "create local temporary table";
|
||||
case GLOBAL -> "create global temporary table";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5005,20 +4953,13 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* Obtain a {@link RowLockStrategy} for the given {@link LockMode}.
|
||||
*/
|
||||
public RowLockStrategy getLockRowIdentifier(LockMode lockMode) {
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_READ:
|
||||
return getReadRowLockStrategy();
|
||||
case WRITE:
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
case PESSIMISTIC_WRITE:
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
case UPGRADE_NOWAIT: {
|
||||
return getWriteRowLockStrategy();
|
||||
}
|
||||
default: {
|
||||
return RowLockStrategy.NONE;
|
||||
}
|
||||
}
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_READ ->
|
||||
getReadRowLockStrategy();
|
||||
case WRITE, PESSIMISTIC_FORCE_INCREMENT, PESSIMISTIC_WRITE, UPGRADE_SKIPLOCKED, UPGRADE_NOWAIT ->
|
||||
getWriteRowLockStrategy();
|
||||
default -> RowLockStrategy.NONE;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5121,9 +5062,9 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
*/
|
||||
public String[] getTruncateTableStatements(String[] tableNames) {
|
||||
if ( canBatchTruncate() ) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for ( String tableName : tableNames ) {
|
||||
if ( builder.length() > 0 ) {
|
||||
if ( !builder.isEmpty() ) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append( tableName );
|
||||
|
@ -5131,7 +5072,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
return new String[] { getTruncateTableStatement( builder.toString() ) };
|
||||
}
|
||||
else {
|
||||
String[] statements = new String[tableNames.length];
|
||||
final String[] statements = new String[tableNames.length];
|
||||
for ( int i = 0; i < tableNames.length; i++ ) {
|
||||
statements[i] = getTruncateTableStatement( tableNames[i] );
|
||||
}
|
||||
|
@ -5364,25 +5305,18 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* {@link ExtractFunction}.
|
||||
*/
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_MONTH: return "dd";
|
||||
case DAY_OF_YEAR: return "dy";
|
||||
case DAY_OF_WEEK: return "dw";
|
||||
return switch (unit) {
|
||||
case DAY_OF_MONTH -> "dd";
|
||||
case DAY_OF_YEAR -> "dy";
|
||||
case DAY_OF_WEEK -> "dw";
|
||||
|
||||
//all the following fields are desugared
|
||||
//by ExtractFunction, so we should never
|
||||
//see them here!
|
||||
case OFFSET:
|
||||
case NATIVE:
|
||||
case NANOSECOND:
|
||||
case DATE:
|
||||
case TIME:
|
||||
case WEEK_OF_MONTH:
|
||||
case WEEK_OF_YEAR:
|
||||
throw new IllegalArgumentException("illegal field: " + unit);
|
||||
|
||||
default: return unit.toString();
|
||||
}
|
||||
// all the following fields are desugared
|
||||
// by ExtractFunction, so we should never
|
||||
// see them here!
|
||||
case OFFSET, NATIVE, NANOSECOND, DATE, TIME, WEEK_OF_MONTH, WEEK_OF_YEAR ->
|
||||
throw new IllegalArgumentException( "illegal field: " + unit );
|
||||
default -> unit.toString();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5408,22 +5342,12 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* which are not units of duration.
|
||||
*/
|
||||
public String translateDurationField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_MONTH:
|
||||
case DAY_OF_YEAR:
|
||||
case DAY_OF_WEEK:
|
||||
case OFFSET:
|
||||
case TIMEZONE_HOUR:
|
||||
case TIMEZONE_MINUTE:
|
||||
case DATE:
|
||||
case TIME:
|
||||
case WEEK_OF_MONTH:
|
||||
case WEEK_OF_YEAR:
|
||||
throw new IllegalArgumentException("illegal unit: " + unit);
|
||||
|
||||
case NATIVE: return "nanosecond"; //default to nanosecond for now
|
||||
default: return unit.toString();
|
||||
}
|
||||
return switch (unit) {
|
||||
case NATIVE -> "nanosecond"; // default to nanosecond for now
|
||||
case DAY_OF_MONTH, DAY_OF_YEAR, DAY_OF_WEEK, WEEK_OF_MONTH, WEEK_OF_YEAR, OFFSET, TIMEZONE_HOUR, TIMEZONE_MINUTE, DATE, TIME ->
|
||||
throw new IllegalArgumentException( "illegal unit: " + unit );
|
||||
default -> unit.toString();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5433,6 +5357,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -5460,7 +5385,12 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
* Append a datetime literal representing the given {@link Date}
|
||||
* value to the given {@link SqlAppender}.
|
||||
*/
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
|
@ -5489,6 +5419,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -5614,7 +5545,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
*/
|
||||
public String getCheckConstraintString(CheckConstraint checkConstraint) {
|
||||
final String constraintName = checkConstraint.getName();
|
||||
String constraint = constraintName == null
|
||||
final String constraint = constraintName == null
|
||||
? " check (" + checkConstraint.getConstraint() + ")"
|
||||
: " constraint " + constraintName + " check (" + checkConstraint.getConstraint() + ")";
|
||||
return appendCheckConstraintOptions( checkConstraint, constraint );
|
||||
|
|
|
@ -295,12 +295,12 @@ public class DialectDelegateWrapper extends Dialect {
|
|||
return wrapped.supportsFractionalTimestampArithmetic();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
return wrapped.timestampdiffPattern( unit, fromTemporalType, toTemporalType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
return wrapped.timestampaddPattern( unit, temporalType, intervalType );
|
||||
}
|
||||
|
@ -1566,13 +1566,19 @@ public class DialectDelegateWrapper extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
wrapped.appendDateTimeLiteral( appender, temporalAccessor, precision, jdbcTimeZone );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
wrapped.appendDateTimeLiteral( appender, date, precision, jdbcTimeZone );
|
||||
}
|
||||
|
||||
|
@ -1580,6 +1586,7 @@ public class DialectDelegateWrapper extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
wrapped.appendDateTimeLiteral( appender, calendar, precision, jdbcTimeZone );
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.hibernate.exception.LockAcquisitionException;
|
|||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -80,6 +79,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
|
||||
import static org.hibernate.type.SqlTypes.BIGINT;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
|
@ -193,38 +193,25 @@ public class H2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
return switch (sqlTypeCode) {
|
||||
// h2 recognizes NCHAR and NCLOB as aliases
|
||||
// but, according to the docs, not NVARCHAR
|
||||
// so just normalize all these types
|
||||
case NCHAR:
|
||||
return columnType( CHAR );
|
||||
case NVARCHAR:
|
||||
return columnType( VARCHAR );
|
||||
case NCLOB:
|
||||
return columnType( CLOB );
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
case NCHAR -> columnType( CHAR );
|
||||
case NVARCHAR -> columnType( VARCHAR );
|
||||
case NCLOB -> columnType( CLOB );
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String castType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case CHAR:
|
||||
case NCHAR:
|
||||
return "char";
|
||||
case VARCHAR:
|
||||
case NVARCHAR:
|
||||
case LONG32VARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
return "varchar";
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
return "varbinary";
|
||||
}
|
||||
return super.castType( sqlTypeCode );
|
||||
return switch (sqlTypeCode) {
|
||||
case CHAR, NCHAR -> "char";
|
||||
case VARCHAR, NVARCHAR, LONG32VARCHAR, LONG32NVARCHAR -> "varchar";
|
||||
case BINARY, VARBINARY, LONG32VARBINARY -> "varbinary";
|
||||
default -> super.castType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -366,12 +353,11 @@ public class H2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected Integer resolveSqlTypeCode(String columnTypeName, TypeConfiguration typeConfiguration) {
|
||||
switch ( columnTypeName ) {
|
||||
case "FLOAT(24)":
|
||||
// Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
return Types.REAL;
|
||||
}
|
||||
return super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
return switch (columnTypeName) {
|
||||
// Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
case "FLOAT(24)" -> Types.REAL;
|
||||
default -> super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -402,11 +388,10 @@ public class H2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected Integer resolveSqlTypeCode(String typeName, String baseTypeName, TypeConfiguration typeConfiguration) {
|
||||
switch ( baseTypeName ) {
|
||||
case "CHARACTER VARYING":
|
||||
return VARCHAR;
|
||||
}
|
||||
return super.resolveSqlTypeCode( typeName, baseTypeName, typeConfiguration );
|
||||
return switch (baseTypeName) {
|
||||
case "CHARACTER VARYING" -> VARCHAR;
|
||||
default -> super.resolveSqlTypeCode( typeName, baseTypeName, typeConfiguration );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -453,7 +438,7 @@ public class H2Dialect extends Dialect {
|
|||
: super.extractPattern(unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
if ( intervalType != null ) {
|
||||
return "(?2+?3)";
|
||||
|
@ -465,7 +450,7 @@ public class H2Dialect extends Dialect {
|
|||
: "dateadd(?1,?2,?3)";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
if ( unit == null ) {
|
||||
return "(?3-?2)";
|
||||
|
@ -477,6 +462,7 @@ public class H2Dialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -514,7 +500,12 @@ public class H2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "date '" );
|
||||
|
@ -546,6 +537,7 @@ public class H2Dialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -745,37 +737,31 @@ public class H2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
final String constraintName;
|
||||
|
||||
switch (errorCode) {
|
||||
case 23505:
|
||||
// Unique constraint violation
|
||||
constraintName = getViolatedConstraintNameExtractor().extractConstraintName(sqlException);
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
constraintName
|
||||
);
|
||||
case 40001:
|
||||
// DEADLOCK DETECTED
|
||||
return new LockAcquisitionException(message, sqlException, sql);
|
||||
case 50200:
|
||||
// LOCK NOT AVAILABLE
|
||||
return new PessimisticLockException(message, sqlException, sql);
|
||||
case 90006:
|
||||
// NULL not allowed for column [90006-145]
|
||||
constraintName = getViolatedConstraintNameExtractor().extractConstraintName(sqlException);
|
||||
return new ConstraintViolationException(message, sqlException, sql, constraintName);
|
||||
case 57014:
|
||||
return new QueryTimeoutException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
return (sqlException, message, sql) ->
|
||||
switch ( extractErrorCode( sqlException ) ) {
|
||||
case 23505 ->
|
||||
// Unique constraint violation
|
||||
new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
case 40001 ->
|
||||
// DEADLOCK DETECTED
|
||||
new LockAcquisitionException(message, sqlException, sql);
|
||||
case 50200 ->
|
||||
// LOCK NOT AVAILABLE
|
||||
new PessimisticLockException(message, sqlException, sql);
|
||||
case 90006 ->
|
||||
// NULL not allowed for column [90006-145]
|
||||
new ConstraintViolationException( message, sqlException, sql,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName(sqlException) );
|
||||
case 57014 ->
|
||||
new QueryTimeoutException( message, sqlException, sql );
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -898,11 +884,11 @@ public class H2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_MONTH: return "day";
|
||||
case WEEK: return "iso_week";
|
||||
default: return unit.toString();
|
||||
}
|
||||
return switch (unit) {
|
||||
case DAY_OF_MONTH -> "day";
|
||||
case WEEK -> "iso_week";
|
||||
default -> unit.toString();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.hibernate.exception.ConstraintViolationException;
|
|||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
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.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
|
@ -58,6 +57,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
|
||||
import static org.hibernate.type.SqlTypes.DOUBLE;
|
||||
import static org.hibernate.type.SqlTypes.NCLOB;
|
||||
|
||||
|
@ -108,22 +108,19 @@ public class HSQLDialect extends Dialect {
|
|||
// But using these types results in schema validation issue as
|
||||
// described in HHH-9693.
|
||||
|
||||
switch ( sqlTypeCode ) {
|
||||
return switch (sqlTypeCode) {
|
||||
//HSQL has no 'nclob' type, but 'clob' is Unicode (See HHH-10364)
|
||||
case NCLOB:
|
||||
return "clob";
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
case NCLOB -> "clob";
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer resolveSqlTypeCode(String typeName, String baseTypeName, TypeConfiguration typeConfiguration) {
|
||||
switch ( baseTypeName ) {
|
||||
case "DOUBLE":
|
||||
return DOUBLE;
|
||||
}
|
||||
return super.resolveSqlTypeCode( typeName, baseTypeName, typeConfiguration );
|
||||
return switch (baseTypeName) {
|
||||
case "DOUBLE" -> DOUBLE;
|
||||
default -> super.resolveSqlTypeCode( typeName, baseTypeName, typeConfiguration );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -288,10 +285,10 @@ public class HSQLDialect extends Dialect {
|
|||
return super.castPattern( from, to );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
StringBuilder pattern = new StringBuilder();
|
||||
boolean castTo = temporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
final StringBuilder pattern = new StringBuilder();
|
||||
final boolean castTo = temporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
switch (unit) {
|
||||
case NANOSECOND:
|
||||
case NATIVE:
|
||||
|
@ -308,7 +305,7 @@ public class HSQLDialect extends Dialect {
|
|||
default:
|
||||
pattern.append("dateadd('?1',?2,");
|
||||
}
|
||||
if (castTo) {
|
||||
if ( castTo ) {
|
||||
pattern.append("cast(?3 as timestamp)");
|
||||
}
|
||||
else {
|
||||
|
@ -318,11 +315,11 @@ public class HSQLDialect extends Dialect {
|
|||
return pattern.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
StringBuilder pattern = new StringBuilder();
|
||||
boolean castFrom = fromTemporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
boolean castTo = toTemporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
final StringBuilder pattern = new StringBuilder();
|
||||
final boolean castFrom = fromTemporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
final boolean castTo = toTemporalType != TemporalType.TIMESTAMP && !unit.isDateUnit();
|
||||
switch (unit) {
|
||||
case NANOSECOND:
|
||||
case NATIVE:
|
||||
|
@ -356,12 +353,9 @@ public class HSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
if ( unit == TemporalUnit.EPOCH ) {
|
||||
return "unix_timestamp(?2)";
|
||||
}
|
||||
else {
|
||||
return super.extractPattern(unit);
|
||||
}
|
||||
return unit == TemporalUnit.EPOCH
|
||||
? "unix_timestamp(?2)"
|
||||
: super.extractPattern( unit );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -419,72 +413,43 @@ public class HSQLDialect extends Dialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtractor EXTRACTOR_20 =
|
||||
// messages may be localized, therefore use the common, non-locale element " table: "
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle -> {
|
||||
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
|
||||
case -8:
|
||||
case -9:
|
||||
case -104:
|
||||
case -177:
|
||||
return extractUsingTemplate(
|
||||
"; ", " table: ",
|
||||
sqle.getMessage()
|
||||
);
|
||||
}
|
||||
return null;
|
||||
} );
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle ->
|
||||
switch ( extractErrorCode( sqle ) ) {
|
||||
case -8, -9, -104, -177 -> extractUsingTemplate( "; ", " table: ", sqle.getMessage() );
|
||||
default -> null;
|
||||
});
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
final String constraintName;
|
||||
|
||||
switch ( errorCode ) {
|
||||
case -104:
|
||||
// Unique constraint violation
|
||||
constraintName = getViolatedConstraintNameExtractor().extractConstraintName(sqlException);
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
constraintName
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
return (sqlException, message, sql) ->
|
||||
switch ( extractErrorCode( sqlException ) ) {
|
||||
case -104 ->
|
||||
// Unique constraint violation
|
||||
new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName(sqlException)
|
||||
);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) {
|
||||
switch ( sqlType ) {
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.CHAR:
|
||||
return "cast(null as varchar(100))";
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BINARY:
|
||||
return "cast(null as varbinary(100))";
|
||||
case Types.CLOB:
|
||||
return "cast(null as clob)";
|
||||
case Types.BLOB:
|
||||
return "cast(null as blob)";
|
||||
case Types.DATE:
|
||||
return "cast(null as date)";
|
||||
case Types.TIMESTAMP:
|
||||
case Types.TIMESTAMP_WITH_TIMEZONE:
|
||||
return "cast(null as timestamp)";
|
||||
case Types.BOOLEAN:
|
||||
return "cast(null as boolean)";
|
||||
case Types.BIT:
|
||||
return "cast(null as bit)";
|
||||
case Types.TIME:
|
||||
return "cast(null as time)";
|
||||
default:
|
||||
return "cast(null as int)";
|
||||
}
|
||||
return switch (sqlType) {
|
||||
case Types.LONGVARCHAR, Types.VARCHAR, Types.CHAR -> "cast(null as varchar(100))";
|
||||
case Types.LONGVARBINARY, Types.VARBINARY, Types.BINARY -> "cast(null as varbinary(100))";
|
||||
case Types.CLOB -> "cast(null as clob)";
|
||||
case Types.BLOB -> "cast(null as blob)";
|
||||
case Types.DATE -> "cast(null as date)";
|
||||
case Types.TIMESTAMP, Types.TIMESTAMP_WITH_TIMEZONE -> "cast(null as timestamp)";
|
||||
case Types.BOOLEAN -> "cast(null as boolean)";
|
||||
case Types.BIT -> "cast(null as bit)";
|
||||
case Types.TIME -> "cast(null as time)";
|
||||
default -> "cast(null as int)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -129,10 +129,8 @@ public class MariaDBDialect extends MySQLDialect {
|
|||
JdbcTypeRegistry jdbcTypeRegistry) {
|
||||
switch ( jdbcTypeCode ) {
|
||||
case OTHER:
|
||||
switch ( columnTypeName ) {
|
||||
case "uuid":
|
||||
jdbcTypeCode = UUID;
|
||||
break;
|
||||
if ( columnTypeName.equals("uuid") ) {
|
||||
jdbcTypeCode = UUID;
|
||||
}
|
||||
break;
|
||||
case VARBINARY:
|
||||
|
|
|
@ -46,7 +46,6 @@ import org.hibernate.exception.LockTimeoutException;
|
|||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
|
@ -87,7 +86,10 @@ import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
|||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static java.lang.Integer.parseInt;
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
import static org.hibernate.type.SqlTypes.BIGINT;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
import static org.hibernate.type.SqlTypes.BIT;
|
||||
|
@ -215,9 +217,9 @@ public class MySQLDialect extends Dialect {
|
|||
final String[] components = StringHelper.split( ".-", versionString );
|
||||
if ( components.length >= 3 ) {
|
||||
try {
|
||||
final int majorVersion = Integer.parseInt( components[0] );
|
||||
final int minorVersion = Integer.parseInt( components[1] );
|
||||
final int patchLevel = Integer.parseInt( components[2] );
|
||||
final int majorVersion = parseInt( components[0] );
|
||||
final int minorVersion = parseInt( components[1] );
|
||||
final int patchLevel = parseInt( components[2] );
|
||||
return DatabaseVersion.make( majorVersion, minorVersion, patchLevel );
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
|
@ -260,36 +262,26 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
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";
|
||||
return switch (sqlTypeCode) {
|
||||
// HHH-6935: Don't use "boolean" i.e. tinyint(1) due to JDBC ResultSetMetaData
|
||||
case BOOLEAN -> "bit";
|
||||
|
||||
case TIMESTAMP:
|
||||
return "datetime($p)";
|
||||
case TIMESTAMP_WITH_TIMEZONE:
|
||||
return "timestamp($p)";
|
||||
case NUMERIC:
|
||||
// it's just a synonym
|
||||
return columnType( DECIMAL );
|
||||
case TIMESTAMP -> "datetime($p)";
|
||||
case TIMESTAMP_WITH_TIMEZONE -> "timestamp($p)";
|
||||
|
||||
case NUMERIC -> columnType( DECIMAL ); // it's just a synonym
|
||||
|
||||
// on MySQL 8, the nchar/nvarchar types use a deprecated character set
|
||||
case NCHAR:
|
||||
return "char($l) character set utf8mb4";
|
||||
case NVARCHAR:
|
||||
return "varchar($l) character set utf8mb4";
|
||||
case NCHAR -> "char($l) character set utf8mb4";
|
||||
case NVARCHAR -> "varchar($l) character set utf8mb4";
|
||||
|
||||
// the maximum long LOB length is 4_294_967_295, bigger than any Java string
|
||||
case BLOB:
|
||||
return "longblob";
|
||||
case NCLOB:
|
||||
return "longtext character set utf8mb4";
|
||||
case CLOB:
|
||||
return "longtext";
|
||||
case BLOB -> "longblob";
|
||||
case NCLOB -> "longtext character set utf8mb4";
|
||||
case CLOB -> "longtext";
|
||||
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -300,40 +292,22 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
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 VARCHAR:
|
||||
case LONG32VARCHAR:
|
||||
//MySQL doesn't let you cast to TEXT/LONGTEXT
|
||||
return "char";
|
||||
case NCHAR:
|
||||
case NVARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
return "char character set utf8mb4";
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
//MySQL doesn't let you cast to BLOB/TINYBLOB/LONGBLOB
|
||||
return "binary";
|
||||
}
|
||||
return super.castType( sqlTypeCode );
|
||||
return switch (sqlTypeCode) {
|
||||
// special case for casting to Boolean
|
||||
case BOOLEAN, BIT -> "unsigned";
|
||||
// MySQL doesn't let you cast to INTEGER/BIGINT/TINYINT
|
||||
case TINYINT, SMALLINT, INTEGER, BIGINT -> "signed";
|
||||
// MySQL doesn't let you cast to DOUBLE/FLOAT
|
||||
// but don't just return 'decimal' because
|
||||
// the default scale is 0 (no decimal places)
|
||||
case FLOAT, REAL, DOUBLE -> "decimal($p,$s)";
|
||||
// MySQL doesn't let you cast to TEXT/LONGTEXT
|
||||
case CHAR, VARCHAR, LONG32VARCHAR -> "char";
|
||||
case NCHAR, NVARCHAR, LONG32NVARCHAR -> "char character set utf8mb4";
|
||||
// MySQL doesn't let you cast to BLOB/TINYBLOB/LONGBLOB
|
||||
case BINARY, VARBINARY, LONG32VARBINARY -> "binary";
|
||||
default -> super.castType(sqlTypeCode);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -452,29 +426,12 @@ public class MySQLDialect extends Dialect {
|
|||
final String characterSet = rs.getString( 1 );
|
||||
final int collationIndex = characterSet.indexOf( '_' );
|
||||
// According to https://dev.mysql.com/doc/refman/8.0/en/charset-charsets.html
|
||||
switch ( collationIndex == -1 ? characterSet : characterSet.substring( 0, collationIndex ) ) {
|
||||
case "utf16":
|
||||
case "utf16le":
|
||||
case "utf32":
|
||||
case "utf8mb4":
|
||||
case "gb18030":
|
||||
return 4;
|
||||
case "utf8":
|
||||
case "utf8mb3":
|
||||
case "eucjpms":
|
||||
case "ujis":
|
||||
return 3;
|
||||
case "ucs2":
|
||||
case "cp932":
|
||||
case "big5":
|
||||
case "euckr":
|
||||
case "gb2312":
|
||||
case "gbk":
|
||||
case "sjis":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return switch ( collationIndex == -1 ? characterSet : characterSet.substring( 0, collationIndex ) ) {
|
||||
case "utf16", "utf16le", "utf32", "utf8mb4", "gb18030" -> 4;
|
||||
case "utf8", "utf8mb3", "eucjpms", "ujis" -> 3;
|
||||
case "ucs2", "cp932", "big5", "euckr", "gb2312", "gbk", "sjis" -> 2;
|
||||
default -> 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
|
@ -489,17 +446,12 @@ public class MySQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
private static int maxVarcharLength(DatabaseVersion version, int bytesPerCharacter) {
|
||||
switch ( bytesPerCharacter ) {
|
||||
case 1:
|
||||
return 65_535;
|
||||
case 2:
|
||||
return 32_767;
|
||||
case 3:
|
||||
return 21_844;
|
||||
case 4:
|
||||
default:
|
||||
return 16_383;
|
||||
}
|
||||
return switch (bytesPerCharacter) {
|
||||
case 1 -> 65_535;
|
||||
case 2 -> 32_767;
|
||||
case 3 -> 21_844;
|
||||
default -> 16_383;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -519,11 +471,11 @@ public class MySQLDialect extends Dialect {
|
|||
@Override
|
||||
public String getNullColumnString(String columnType) {
|
||||
// Good job MySQL https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html
|
||||
// If the explicit_defaults_for_timestamp system variable is enabled, TIMESTAMP columns permit NULL values only if declared with the NULL attribute.
|
||||
if ( columnType.regionMatches( true, 0, "timestamp", 0, "timestamp".length() ) ) {
|
||||
return " null";
|
||||
}
|
||||
return super.getNullColumnString( columnType );
|
||||
// If the explicit_defaults_for_timestamp system variable is enabled, TIMESTAMP columns
|
||||
// permit NULL values only if declared with the NULL attribute.
|
||||
return columnType.regionMatches( true, 0, "timestamp", 0, "timestamp".length() )
|
||||
? " null"
|
||||
: super.getNullColumnString( columnType );
|
||||
}
|
||||
|
||||
public DatabaseVersion getMySQLVersion() {
|
||||
|
@ -574,12 +526,7 @@ public class MySQLDialect extends Dialect {
|
|||
int displaySize) {
|
||||
// It seems MariaDB/MySQL return the precision in bytes depending on the charset,
|
||||
// so to detect whether we have a single character here, we check the display size
|
||||
if ( jdbcTypeCode == Types.CHAR && precision <= 4 ) {
|
||||
return displaySize;
|
||||
}
|
||||
else {
|
||||
return precision;
|
||||
}
|
||||
return jdbcTypeCode == Types.CHAR && precision <= 4 ? displaySize : precision;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -747,9 +694,8 @@ public class MySQLDialect extends Dialect {
|
|||
private void time(FunctionContributions queryEngine) {
|
||||
queryEngine.getFunctionRegistry().namedDescriptorBuilder( "time" )
|
||||
.setExactArgumentCount( 1 )
|
||||
.setInvariantType(
|
||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||
)
|
||||
.setInvariantType( queryEngine.getTypeConfiguration().getBasicTypeRegistry()
|
||||
.resolve( StandardBasicTypes.STRING ) )
|
||||
.register();
|
||||
}
|
||||
|
||||
|
@ -791,58 +737,45 @@ public class MySQLDialect extends Dialect {
|
|||
* extract() function, but we can emulate some of them by
|
||||
* using the appropriate named functions instead of
|
||||
* extract().
|
||||
*
|
||||
* <p>
|
||||
* Thus, the additional supported fields are
|
||||
* {@link TemporalUnit#DAY_OF_YEAR},
|
||||
* {@link TemporalUnit#DAY_OF_MONTH},
|
||||
* {@link TemporalUnit#DAY_OF_YEAR}.
|
||||
*
|
||||
* <p>
|
||||
* In addition, the field {@link TemporalUnit#SECOND} is
|
||||
* redefined to include microseconds.
|
||||
*/
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
switch (unit) {
|
||||
case SECOND:
|
||||
return "(second(?2)+microsecond(?2)/1e6)";
|
||||
case WEEK:
|
||||
return "weekofyear(?2)"; //same as week(?2,3), the ISO week
|
||||
case DAY_OF_WEEK:
|
||||
return "dayofweek(?2)";
|
||||
case DAY_OF_MONTH:
|
||||
return "dayofmonth(?2)";
|
||||
case DAY_OF_YEAR:
|
||||
return "dayofyear(?2)";
|
||||
return switch (unit) {
|
||||
case SECOND -> "(second(?2)+microsecond(?2)/1e6)";
|
||||
case WEEK -> "weekofyear(?2)"; // same as week(?2,3), the ISO week
|
||||
case DAY_OF_WEEK -> "dayofweek(?2)";
|
||||
case DAY_OF_MONTH -> "dayofmonth(?2)";
|
||||
case DAY_OF_YEAR -> "dayofyear(?2)";
|
||||
//TODO: case WEEK_YEAR: yearweek(?2, 3)/100
|
||||
case EPOCH:
|
||||
return "unix_timestamp(?2)";
|
||||
default:
|
||||
return "?1(?2)";
|
||||
}
|
||||
case EPOCH -> "unix_timestamp(?2)";
|
||||
default -> "?1(?2)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
switch (unit) {
|
||||
case NANOSECOND:
|
||||
return "timestampadd(microsecond,(?2)/1e3,?3)";
|
||||
case NATIVE:
|
||||
return "timestampadd(microsecond,?2,?3)";
|
||||
default:
|
||||
return "timestampadd(?1,?2,?3)";
|
||||
}
|
||||
return switch (unit) {
|
||||
case NANOSECOND -> "timestampadd(microsecond,(?2)/1e3,?3)";
|
||||
case NATIVE -> "timestampadd(microsecond,?2,?3)";
|
||||
default -> "timestampadd(?1,?2,?3)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
switch (unit) {
|
||||
case NANOSECOND:
|
||||
return "timestampdiff(microsecond,?2,?3)*1e3";
|
||||
case NATIVE:
|
||||
return "timestampdiff(microsecond,?2,?3)";
|
||||
default:
|
||||
return "timestampdiff(?1,?2,?3)";
|
||||
}
|
||||
return switch (unit) {
|
||||
case NANOSECOND -> "timestampdiff(microsecond,?2,?3)*1e3";
|
||||
case NATIVE -> "timestampdiff(microsecond,?2,?3)";
|
||||
default -> "timestampdiff(?1,?2,?3)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -854,6 +787,7 @@ public class MySQLDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -881,7 +815,12 @@ public class MySQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "date '" );
|
||||
|
@ -907,6 +846,7 @@ public class MySQLDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -942,7 +882,7 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getEnumTypeDeclaration(String name, String[] values) {
|
||||
StringBuilder type = new StringBuilder();
|
||||
final StringBuilder type = new StringBuilder();
|
||||
type.append( "enum (" );
|
||||
String separator = "";
|
||||
for ( String value : values ) {
|
||||
|
@ -971,12 +911,12 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtractor EXTRACTOR =
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle -> {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqle );
|
||||
final String sqlState = extractSqlState( sqle );
|
||||
if ( sqlState != null ) {
|
||||
switch ( Integer.parseInt( sqlState ) ) {
|
||||
case 23000:
|
||||
return extractUsingTemplate( " for key '", "'", sqle.getMessage() );
|
||||
}
|
||||
return switch ( parseInt( sqlState ) ) {
|
||||
case 23000 -> extractUsingTemplate( " for key '", "'", sqle.getMessage() );
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
return null;
|
||||
} );
|
||||
|
@ -1105,7 +1045,6 @@ public class MySQLDialect extends Dialect {
|
|||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||
EntityMappingType rootEntityDescriptor,
|
||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||
|
||||
return new LocalTemporaryTableMutationStrategy(
|
||||
TemporaryTable.createIdTable(
|
||||
rootEntityDescriptor,
|
||||
|
@ -1121,7 +1060,6 @@ public class MySQLDialect extends Dialect {
|
|||
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
|
||||
EntityMappingType rootEntityDescriptor,
|
||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||
|
||||
return new LocalTemporaryTableInsertStrategy(
|
||||
TemporaryTable.createEntityTable(
|
||||
rootEntityDescriptor,
|
||||
|
@ -1242,17 +1180,16 @@ public class MySQLDialect extends Dialect {
|
|||
return new LockAcquisitionException( message, sqlException, sql );
|
||||
case 1062:
|
||||
// Unique constraint violation
|
||||
String constraintName = getViolatedConstraintNameExtractor().extractConstraintName(sqlException);
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
constraintName
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
}
|
||||
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final String sqlState = extractSqlState( sqlException );
|
||||
if ( sqlState != null ) {
|
||||
switch ( sqlState ) {
|
||||
case "41000":
|
||||
|
@ -1413,16 +1350,12 @@ public class MySQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
private String withTimeout(String lockString, int timeout) {
|
||||
switch (timeout) {
|
||||
case LockOptions.NO_WAIT:
|
||||
return supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case LockOptions.SKIP_LOCKED:
|
||||
return supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
case LockOptions.WAIT_FOREVER:
|
||||
return lockString;
|
||||
default:
|
||||
return supportsWait() ? lockString + " wait " + getTimeoutInSeconds( timeout ) : lockString;
|
||||
}
|
||||
return switch (timeout) {
|
||||
case LockOptions.NO_WAIT -> supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case LockOptions.SKIP_LOCKED -> supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
case LockOptions.WAIT_FOREVER -> lockString;
|
||||
default -> supportsWait() ? lockString + " wait " + getTimeoutInSeconds( timeout ) : lockString;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1432,7 +1365,7 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getWriteLockString(String aliases, int timeout) {
|
||||
return withTimeout( getForUpdateString(aliases), timeout );
|
||||
return withTimeout( getForUpdateString( aliases ), timeout );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1443,7 +1376,7 @@ public class MySQLDialect extends Dialect {
|
|||
@Override
|
||||
public String getReadLockString(String aliases, int timeout) {
|
||||
if ( supportsAliasLocks() && supportsForShare() ) {
|
||||
return withTimeout(" for share of " + aliases, timeout );
|
||||
return withTimeout( " for share of " + aliases, timeout );
|
||||
}
|
||||
else {
|
||||
// fall back to locking all aliases
|
||||
|
@ -1576,9 +1509,8 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
return isNotEmpty( checkConstraint.getOptions() )
|
||||
? sqlCheckConstraint + " " + checkConstraint.getOptions()
|
||||
: sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,9 @@ import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABA
|
|||
import static org.hibernate.dialect.OracleJdbcHelper.getArrayJdbcTypeConstructor;
|
||||
import static org.hibernate.dialect.OracleJdbcHelper.getNestedTableJdbcTypeConstructor;
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
|
||||
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.HOUR;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.MINUTE;
|
||||
|
@ -561,37 +563,26 @@ public class OracleDialect extends Dialect {
|
|||
*/
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
switch (unit) {
|
||||
case DAY_OF_WEEK:
|
||||
return "to_number(to_char(?2,'D'))";
|
||||
case DAY_OF_MONTH:
|
||||
return "to_number(to_char(?2,'DD'))";
|
||||
case DAY_OF_YEAR:
|
||||
return "to_number(to_char(?2,'DDD'))";
|
||||
case WEEK:
|
||||
return "to_number(to_char(?2,'IW'))"; //the ISO week number
|
||||
case WEEK_OF_YEAR:
|
||||
return "to_number(to_char(?2,'WW'))";
|
||||
return switch (unit) {
|
||||
case DAY_OF_WEEK -> "to_number(to_char(?2,'D'))";
|
||||
case DAY_OF_MONTH -> "to_number(to_char(?2,'DD'))";
|
||||
case DAY_OF_YEAR -> "to_number(to_char(?2,'DDD'))";
|
||||
case WEEK -> "to_number(to_char(?2,'IW'))"; // the ISO week number
|
||||
case WEEK_OF_YEAR -> "to_number(to_char(?2,'WW'))";
|
||||
// Oracle doesn't support extracting the quarter
|
||||
case QUARTER:
|
||||
return "to_number(to_char(?2,'Q'))";
|
||||
case QUARTER -> "to_number(to_char(?2,'Q'))";
|
||||
// Oracle can't extract time parts from a date column, so we need to cast to timestamp
|
||||
// This is because Oracle treats date as ANSI SQL date which has no time part
|
||||
// Also see https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions052.htm#SQLRF00639
|
||||
case HOUR:
|
||||
return "to_number(to_char(?2,'HH24'))";
|
||||
case MINUTE:
|
||||
return "to_number(to_char(?2,'MI'))";
|
||||
case SECOND:
|
||||
return "to_number(to_char(?2,'SS'))";
|
||||
case EPOCH:
|
||||
return "trunc((cast(?2 at time zone 'UTC' as date) - date '1970-1-1')*86400)";
|
||||
default:
|
||||
return super.extractPattern(unit);
|
||||
}
|
||||
case HOUR -> "to_number(to_char(?2,'HH24'))";
|
||||
case MINUTE -> "to_number(to_char(?2,'MI'))";
|
||||
case SECOND -> "to_number(to_char(?2,'SS'))";
|
||||
case EPOCH -> "trunc((cast(?2 at time zone 'UTC' as date) - date '1970-1-1')*86400)";
|
||||
default -> super.extractPattern(unit);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
final StringBuilder pattern = new StringBuilder();
|
||||
switch ( unit ) {
|
||||
|
@ -634,7 +625,7 @@ public class OracleDialect extends Dialect {
|
|||
return pattern.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
final StringBuilder pattern = new StringBuilder();
|
||||
final boolean hasTimePart = toTemporalType != TemporalType.DATE || fromTemporalType != TemporalType.DATE;
|
||||
|
@ -1106,74 +1097,58 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
private static final ViolatedConstraintNameExtractor EXTRACTOR =
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle -> {
|
||||
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
|
||||
case 1:
|
||||
case 2291:
|
||||
case 2292:
|
||||
return extractUsingTemplate( "(", ")", sqle.getMessage() );
|
||||
case 1400:
|
||||
// simple nullability constraint
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} );
|
||||
new TemplatedViolatedConstraintNameExtractor( sqle ->
|
||||
switch ( extractErrorCode( sqle ) ) {
|
||||
case 1, 2291, 2292 -> extractUsingTemplate( "(", ")", sqle.getMessage() );
|
||||
case 1400 -> null; // simple nullability constraint
|
||||
default -> null;
|
||||
});
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final String constraintName;
|
||||
// interpreting Oracle exceptions is much much more precise based on their specific vendor codes.
|
||||
switch ( JdbcExceptionHelper.extractErrorCode( sqlException ) ) {
|
||||
|
||||
// interpreting Oracle exceptions is much more precise based on their specific vendor codes
|
||||
return switch ( extractErrorCode( sqlException ) ) {
|
||||
// lock timeouts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
case 30006:
|
||||
case 30006 ->
|
||||
// ORA-30006: resource busy; acquire with WAIT timeout expired
|
||||
return new LockTimeoutException(message, sqlException, sql);
|
||||
case 54:
|
||||
new LockTimeoutException( message, sqlException, sql );
|
||||
case 54 ->
|
||||
// ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
|
||||
return new LockTimeoutException(message, sqlException, sql);
|
||||
case 4021:
|
||||
new LockTimeoutException( message, sqlException, sql );
|
||||
case 4021 ->
|
||||
// ORA-04021 timeout occurred while waiting to lock object
|
||||
return new LockTimeoutException(message, sqlException, sql);
|
||||
new LockTimeoutException (message, sqlException, sql );
|
||||
|
||||
// deadlocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
case 60:
|
||||
case 60 ->
|
||||
// ORA-00060: deadlock detected while waiting for resource
|
||||
return new LockAcquisitionException( message, sqlException, sql );
|
||||
case 4020:
|
||||
new LockAcquisitionException( message, sqlException, sql );
|
||||
case 4020 ->
|
||||
// ORA-04020 deadlock detected while trying to lock object
|
||||
return new LockAcquisitionException( message, sqlException, sql );
|
||||
new LockAcquisitionException( message, sqlException, sql );
|
||||
|
||||
// query cancelled ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
case 1013:
|
||||
case 1013 ->
|
||||
// ORA-01013: user requested cancel of current operation
|
||||
return new QueryTimeoutException( message, sqlException, sql );
|
||||
new QueryTimeoutException( message, sqlException, sql );
|
||||
|
||||
// data integrity violation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
case 1:
|
||||
case 1 ->
|
||||
// ORA-00001: unique constraint violated
|
||||
constraintName = getViolatedConstraintNameExtractor().extractConstraintName( sqlException );
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
constraintName
|
||||
);
|
||||
case 1407:
|
||||
new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
case 1407 ->
|
||||
// ORA-01407: cannot update column to NULL
|
||||
constraintName = getViolatedConstraintNameExtractor().extractConstraintName( sqlException );
|
||||
return new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
new ConstraintViolationException( message, sqlException, sql,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) );
|
||||
default -> null;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1281,10 +1256,10 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
return DISTINCT_KEYWORD_PATTERN.matcher( sql ).find()
|
||||
|| GROUP_BY_KEYWORD_PATTERN.matcher( sql ).find()
|
||||
|| UNION_KEYWORD_PATTERN.matcher( sql ).find()
|
||||
|| ORDER_BY_KEYWORD_PATTERN.matcher( sql ).find() && queryOptions.hasLimit()
|
||||
|| queryOptions.hasLimit() && queryOptions.getLimit().getFirstRow() != null;
|
||||
|| GROUP_BY_KEYWORD_PATTERN.matcher( sql ).find()
|
||||
|| UNION_KEYWORD_PATTERN.matcher( sql ).find()
|
||||
|| ORDER_BY_KEYWORD_PATTERN.matcher( sql ).find() && queryOptions.hasLimit()
|
||||
|| queryOptions.hasLimit() && queryOptions.getLimit().getFirstRow() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1422,16 +1397,12 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
private String withTimeout(String lockString, int timeout) {
|
||||
switch ( timeout ) {
|
||||
case NO_WAIT:
|
||||
return supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case SKIP_LOCKED:
|
||||
return supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
case WAIT_FOREVER:
|
||||
return lockString;
|
||||
default:
|
||||
return supportsWait() ? lockString + " wait " + getTimeoutInSeconds( timeout ) : lockString;
|
||||
}
|
||||
return switch (timeout) {
|
||||
case NO_WAIT -> supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case SKIP_LOCKED -> supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
case WAIT_FOREVER -> lockString;
|
||||
default -> supportsWait() ? lockString + " wait " + getTimeoutInSeconds( timeout ) : lockString;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1464,13 +1435,19 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, TemporalAccessor temporalAccessor, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
// we usually use the JDBC escape-based syntax
|
||||
// because we want to let the JDBC driver handle
|
||||
// TIME (a concept which does not exist in Oracle)
|
||||
// but for the special case of timestamps with an
|
||||
// offset we need to use the ANSI syntax
|
||||
if ( precision == TemporalType.TIMESTAMP && temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||
if ( precision == TemporalType.TIMESTAMP
|
||||
&& temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||
appender.appendSql( "timestamp '" );
|
||||
appendAsTimestampWithNanos( appender, temporalAccessor, true, jdbcTimeZone, false );
|
||||
appender.appendSql( '\'' );
|
||||
|
@ -1488,8 +1465,8 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format, boolean useFm, boolean resetFm) {
|
||||
String fm = useFm ? "fm" : "";
|
||||
String fmReset = resetFm ? fm : "";
|
||||
final String fm = useFm ? "fm" : "";
|
||||
final String fmReset = resetFm ? fm : "";
|
||||
return new Replacer( format, "'", "\"" )
|
||||
//era
|
||||
.replace("GG", "AD")
|
||||
|
@ -1602,8 +1579,8 @@ public class OracleDialect extends Dialect {
|
|||
@Override
|
||||
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
|
||||
throws SQLException {
|
||||
builder.setAutoQuoteInitialUnderscore(true);
|
||||
return super.buildIdentifierHelper(builder, dbMetaData);
|
||||
builder.setAutoQuoteInitialUnderscore( true );
|
||||
return super.buildIdentifierHelper( builder, dbMetaData );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1641,7 +1618,8 @@ public class OracleDialect extends Dialect {
|
|||
EntityMutationTarget mutationTarget,
|
||||
OptionalTableUpdate optionalTableUpdate,
|
||||
SessionFactoryImplementor factory) {
|
||||
final OracleSqlAstTranslator<?> translator = new OracleSqlAstTranslator<>( factory, optionalTableUpdate );
|
||||
final OracleSqlAstTranslator<?> translator =
|
||||
new OracleSqlAstTranslator<>( factory, optionalTableUpdate );
|
||||
return translator.createMergeOperation( optionalTableUpdate );
|
||||
}
|
||||
|
||||
|
@ -1665,7 +1643,7 @@ public class OracleDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getEnumTypeDeclaration(String name, String[] values) {
|
||||
return getVersion().isSameOrAfter(23) ? name : super.getEnumTypeDeclaration(name, values);
|
||||
return getVersion().isSameOrAfter( 23 ) ? name : super.getEnumTypeDeclaration( name, values );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1718,9 +1696,8 @@ public class OracleDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
return isNotEmpty( checkConstraint.getOptions() )
|
||||
? sqlCheckConstraint + " " + checkConstraint.getOptions()
|
||||
: sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,67 +190,47 @@ public class PostgreSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case TINYINT:
|
||||
// no tinyint, not even in Postgres 11
|
||||
return "smallint";
|
||||
return switch (sqlTypeCode) {
|
||||
// no tinyint, not even in Postgres 11
|
||||
case TINYINT -> "smallint";
|
||||
|
||||
// there are no nchar/nvarchar types in Postgres
|
||||
case NCHAR:
|
||||
return columnType( CHAR );
|
||||
case NVARCHAR:
|
||||
return columnType( VARCHAR );
|
||||
case NCHAR -> columnType( CHAR );
|
||||
case NVARCHAR -> 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
|
||||
case LONG32VARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
return "text";
|
||||
case LONG32VARCHAR, LONG32NVARCHAR -> "text";
|
||||
|
||||
case BLOB:
|
||||
case CLOB:
|
||||
case NCLOB:
|
||||
// use oid as the blob/clob type on Postgres because
|
||||
// the JDBC driver doesn't allow using bytea/text via
|
||||
// LOB APIs
|
||||
return "oid";
|
||||
// use oid as the blob/clob type on Postgres because
|
||||
// the JDBC driver doesn't allow using bytea/text via
|
||||
// LOB APIs
|
||||
case BLOB, CLOB, NCLOB -> "oid";
|
||||
|
||||
// use bytea as the "long" binary type (that there is no
|
||||
// real VARBINARY type in Postgres, so we always use this)
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
return "bytea";
|
||||
case BINARY, VARBINARY, LONG32VARBINARY -> "bytea";
|
||||
|
||||
// We do not use the time with timezone type because PG deprecated it and it lacks certain operations like subtraction
|
||||
// We do not use the 'time with timezone' type because PG
|
||||
// deprecated it, and it lacks certain operations like
|
||||
// subtraction
|
||||
// case TIME_UTC:
|
||||
// return columnType( TIME_WITH_TIMEZONE );
|
||||
|
||||
case TIMESTAMP_UTC:
|
||||
return columnType( TIMESTAMP_WITH_TIMEZONE );
|
||||
case TIMESTAMP_UTC -> columnType( TIMESTAMP_WITH_TIMEZONE );
|
||||
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
default -> super.columnType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String castType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case CHAR:
|
||||
case NCHAR:
|
||||
case VARCHAR:
|
||||
case NVARCHAR:
|
||||
case LONG32VARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
return "text";
|
||||
case BINARY:
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
return "bytea";
|
||||
}
|
||||
return super.castType( sqlTypeCode );
|
||||
return switch (sqlTypeCode) {
|
||||
case CHAR, NCHAR, VARCHAR, NVARCHAR, LONG32VARCHAR, LONG32NVARCHAR -> "text";
|
||||
case BINARY, VARBINARY, LONG32VARBINARY -> "bytea";
|
||||
default -> super.castType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -387,22 +367,15 @@ public class PostgreSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected Integer resolveSqlTypeCode(String columnTypeName, TypeConfiguration typeConfiguration) {
|
||||
switch ( columnTypeName ) {
|
||||
case "bool":
|
||||
return Types.BOOLEAN;
|
||||
case "float4":
|
||||
// Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
return Types.REAL;
|
||||
case "float8":
|
||||
return Types.DOUBLE;
|
||||
case "int2":
|
||||
return Types.SMALLINT;
|
||||
case "int4":
|
||||
return Types.INTEGER;
|
||||
case "int8":
|
||||
return Types.BIGINT;
|
||||
}
|
||||
return super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
return switch (columnTypeName) {
|
||||
case "bool" -> Types.BOOLEAN;
|
||||
case "float4" -> Types.REAL; // Use REAL instead of FLOAT to get Float as recommended Java type
|
||||
case "float8" -> Types.DOUBLE;
|
||||
case "int2" -> Types.SMALLINT;
|
||||
case "int4" -> Types.INTEGER;
|
||||
case "int8" -> Types.BIGINT;
|
||||
default -> super.resolveSqlTypeCode( columnTypeName, typeConfiguration );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -459,12 +432,10 @@ public class PostgreSQLDialect extends Dialect {
|
|||
*/
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case DAY_OF_WEEK:
|
||||
return "(" + super.extractPattern(unit) + "+1)";
|
||||
default:
|
||||
return super.extractPattern(unit);
|
||||
}
|
||||
return switch (unit) {
|
||||
case DAY_OF_WEEK -> "(" + super.extractPattern( unit ) + "+1)";
|
||||
default -> super.extractPattern(unit);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -480,7 +451,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
return 1_000_000_000; //seconds
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
return intervalType != null
|
||||
? "(?2+?3)"
|
||||
|
@ -488,21 +459,16 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
private static String intervalPattern(TemporalUnit unit) {
|
||||
switch (unit) {
|
||||
case NANOSECOND:
|
||||
return "(?2)/1e3*interval '1 microsecond'";
|
||||
case NATIVE:
|
||||
return "(?2)*interval '1 second'";
|
||||
case QUARTER: //quarter is not supported in interval literals
|
||||
return "(?2)*interval '3 month'";
|
||||
case WEEK: //week is not supported in interval literals
|
||||
return "(?2)*interval '7 day'";
|
||||
default:
|
||||
return "(?2)*interval '1 " + unit + "'";
|
||||
}
|
||||
return switch (unit) {
|
||||
case NANOSECOND -> "(?2)/1e3*interval '1 microsecond'";
|
||||
case NATIVE -> "(?2)*interval '1 second'";
|
||||
case QUARTER -> "(?2)*interval '3 month'"; // quarter is not supported in interval literals
|
||||
case WEEK -> "(?2)*interval '7 day'"; // week is not supported in interval literals
|
||||
default -> "(?2)*interval '1 " + unit + "'";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
if ( unit == null ) {
|
||||
return "(?3-?2)";
|
||||
|
@ -511,39 +477,25 @@ public class PostgreSQLDialect extends Dialect {
|
|||
// special case: subtraction of two dates
|
||||
// results in an integer number of days
|
||||
// instead of an INTERVAL
|
||||
switch ( unit ) {
|
||||
case YEAR:
|
||||
case MONTH:
|
||||
case QUARTER:
|
||||
return "extract(" + translateDurationField( unit ) + " from age(?3,?2))";
|
||||
default:
|
||||
return "(?3-?2)" + DAY.conversionFactor( unit, this );
|
||||
}
|
||||
return switch (unit) {
|
||||
case YEAR, MONTH, QUARTER -> "extract(" + translateDurationField( unit ) + " from age(?3,?2))";
|
||||
default -> "(?3-?2)" + DAY.conversionFactor( unit, this );
|
||||
};
|
||||
}
|
||||
else {
|
||||
switch ( unit ) {
|
||||
case YEAR:
|
||||
return "extract(year from ?3-?2)";
|
||||
case QUARTER:
|
||||
return "(extract(year from ?3-?2)*4+extract(month from ?3-?2)/3)";
|
||||
case MONTH:
|
||||
return "(extract(year from ?3-?2)*12+extract(month from ?3-?2))";
|
||||
case WEEK: //week is not supported by extract() when the argument is a duration
|
||||
return "(extract(day from ?3-?2)/7)";
|
||||
case DAY:
|
||||
return "extract(day from ?3-?2)";
|
||||
//in order to avoid multiple calls to extract(),
|
||||
//we use extract(epoch from x - y) * factor for
|
||||
//all the following units:
|
||||
case HOUR:
|
||||
case MINUTE:
|
||||
case SECOND:
|
||||
case NANOSECOND:
|
||||
case NATIVE:
|
||||
return "extract(epoch from ?3-?2)" + EPOCH.conversionFactor( unit, this );
|
||||
default:
|
||||
throw new SemanticException( "Unrecognized field: " + unit );
|
||||
}
|
||||
return switch (unit) {
|
||||
case YEAR -> "extract(year from ?3-?2)";
|
||||
case QUARTER -> "(extract(year from ?3-?2)*4+extract(month from ?3-?2)/3)";
|
||||
case MONTH -> "(extract(year from ?3-?2)*12+extract(month from ?3-?2))";
|
||||
case WEEK -> "(extract(day from ?3-?2)/7)"; // week is not supported by extract() when the argument is a duration
|
||||
case DAY -> "extract(day from ?3-?2)";
|
||||
// in order to avoid multiple calls to extract(),
|
||||
// we use extract(epoch from x - y) * factor for
|
||||
// all the following units:
|
||||
case HOUR, MINUTE, SECOND, NANOSECOND, NATIVE ->
|
||||
"extract(epoch from ?3-?2)" + EPOCH.conversionFactor( unit, this );
|
||||
default -> throw new SemanticException( "Unrecognized field: " + unit );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,27 +771,16 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
}
|
||||
LockMode lockMode = lockOptions.getAliasSpecificLockMode( aliases );
|
||||
if (lockMode == null ) {
|
||||
if ( lockMode == null ) {
|
||||
lockMode = lockOptions.getLockMode();
|
||||
}
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_READ: {
|
||||
return getReadLockString( aliases, lockOptions.getTimeOut() );
|
||||
}
|
||||
case PESSIMISTIC_WRITE: {
|
||||
return getWriteLockString( aliases, lockOptions.getTimeOut() );
|
||||
}
|
||||
case UPGRADE_NOWAIT:
|
||||
case PESSIMISTIC_FORCE_INCREMENT: {
|
||||
return getForUpdateNowaitString(aliases);
|
||||
}
|
||||
case UPGRADE_SKIPLOCKED: {
|
||||
return getForUpdateSkipLockedString(aliases);
|
||||
}
|
||||
default: {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_READ -> getReadLockString( aliases, lockOptions.getTimeOut() );
|
||||
case PESSIMISTIC_WRITE -> getWriteLockString( aliases, lockOptions.getTimeOut() );
|
||||
case UPGRADE_NOWAIT, PESSIMISTIC_FORCE_INCREMENT -> getForUpdateNowaitString( aliases );
|
||||
case UPGRADE_SKIPLOCKED -> getForUpdateSkipLockedString( aliases );
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1141,13 +1082,13 @@ public class PostgreSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
return switch (unit) {
|
||||
//WEEK means the ISO week number on Postgres
|
||||
case DAY_OF_MONTH: return "day";
|
||||
case DAY_OF_YEAR: return "doy";
|
||||
case DAY_OF_WEEK: return "dow";
|
||||
default: return super.translateExtractField( unit );
|
||||
}
|
||||
case DAY_OF_MONTH -> "day";
|
||||
case DAY_OF_YEAR -> "doy";
|
||||
case DAY_OF_WEEK -> "dow";
|
||||
default -> super.translateExtractField( unit );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1166,6 +1107,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -1203,7 +1145,12 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "date '" );
|
||||
|
@ -1229,6 +1176,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -1253,14 +1201,11 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
private String withTimeout(String lockString, int timeout) {
|
||||
switch (timeout) {
|
||||
case LockOptions.NO_WAIT:
|
||||
return supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case LockOptions.SKIP_LOCKED:
|
||||
return supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
default:
|
||||
return lockString;
|
||||
}
|
||||
return switch (timeout) {
|
||||
case LockOptions.NO_WAIT -> supportsNoWait() ? lockString + " nowait" : lockString;
|
||||
case LockOptions.SKIP_LOCKED -> supportsSkipLocked() ? lockString + " skip locked" : lockString;
|
||||
default -> lockString;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1353,16 +1298,11 @@ public class PostgreSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public boolean supportsFetchClause(FetchClauseType type) {
|
||||
switch ( type ) {
|
||||
case ROWS_ONLY:
|
||||
return true;
|
||||
case PERCENT_ONLY:
|
||||
case PERCENT_WITH_TIES:
|
||||
return false;
|
||||
case ROWS_WITH_TIES:
|
||||
return getVersion().isSameOrAfter( 13 );
|
||||
}
|
||||
return false;
|
||||
return switch (type) {
|
||||
case ROWS_ONLY -> true;
|
||||
case PERCENT_ONLY, PERCENT_WITH_TIES -> false;
|
||||
case ROWS_WITH_TIES -> getVersion().isSameOrAfter(13);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1489,7 +1429,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
if ( commentsEnabled && queryOptions.getComment() != null ) {
|
||||
sql = prependComment( sql, queryOptions.getComment() );
|
||||
}
|
||||
if ( queryOptions.getDatabaseHints() != null && queryOptions.getDatabaseHints().size() > 0 ) {
|
||||
if ( queryOptions.getDatabaseHints() != null && !queryOptions.getDatabaseHints().isEmpty() ) {
|
||||
sql = getQueryHintString( sql, queryOptions.getDatabaseHints() );
|
||||
}
|
||||
return sql;
|
||||
|
|
|
@ -82,7 +82,6 @@ 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.TimestampUtcAsJdbcTimestampJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntAsSmallIntJdbcType;
|
||||
|
@ -96,6 +95,9 @@ import jakarta.persistence.TemporalType;
|
|||
|
||||
import static org.hibernate.cfg.DialectSpecificSettings.SQL_SERVER_COMPATIBILITY_LEVEL;
|
||||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
|
||||
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.NANOSECOND;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
|
||||
import static org.hibernate.type.SqlTypes.BLOB;
|
||||
|
@ -153,20 +155,12 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
Integer precision,
|
||||
Integer scale,
|
||||
Long length) {
|
||||
switch ( jdbcType.getDdlTypeCode() ) {
|
||||
case BLOB:
|
||||
case CLOB:
|
||||
case NCLOB:
|
||||
return super.resolveSize(
|
||||
jdbcType,
|
||||
javaType,
|
||||
precision,
|
||||
scale,
|
||||
length == null ? getDefaultLobLength() : length
|
||||
);
|
||||
default:
|
||||
return super.resolveSize( jdbcType, javaType, precision, scale, length );
|
||||
}
|
||||
return switch ( jdbcType.getDdlTypeCode() ) {
|
||||
case BLOB, CLOB, NCLOB ->
|
||||
super.resolveSize( jdbcType, javaType, precision, scale,
|
||||
length == null ? getDefaultLobLength() : length );
|
||||
default -> super.resolveSize( jdbcType, javaType, precision, scale, length );
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -230,54 +224,35 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
protected String columnType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
return switch (sqlTypeCode) {
|
||||
// there is no 'double' type in SQL server
|
||||
// but 'float' is double precision by default
|
||||
case DOUBLE:
|
||||
return "float";
|
||||
case DOUBLE -> "float";
|
||||
// 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 CLOB:
|
||||
return "varchar(max)";
|
||||
case NCLOB:
|
||||
return "nvarchar(max)";
|
||||
case BLOB:
|
||||
return "varbinary(max)";
|
||||
case DATE:
|
||||
return "date";
|
||||
case TIME:
|
||||
return "time";
|
||||
case TIMESTAMP:
|
||||
return "datetime2($p)";
|
||||
case TIME_WITH_TIMEZONE:
|
||||
case TIMESTAMP_WITH_TIMEZONE:
|
||||
return "datetimeoffset($p)";
|
||||
default:
|
||||
return super.columnType( sqlTypeCode );
|
||||
}
|
||||
case CLOB -> "varchar(max)";
|
||||
case NCLOB -> "nvarchar(max)";
|
||||
case BLOB -> "varbinary(max)";
|
||||
case DATE -> "date";
|
||||
case TIME -> "time";
|
||||
case TIMESTAMP -> "datetime2($p)";
|
||||
case TIME_WITH_TIMEZONE, TIMESTAMP_WITH_TIMEZONE -> "datetimeoffset($p)";
|
||||
default -> super.columnType(sqlTypeCode);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String castType(int sqlTypeCode) {
|
||||
switch ( sqlTypeCode ) {
|
||||
case VARCHAR:
|
||||
case LONG32VARCHAR:
|
||||
case CLOB:
|
||||
return "varchar(max)";
|
||||
case NVARCHAR:
|
||||
case LONG32NVARCHAR:
|
||||
case NCLOB:
|
||||
return "nvarchar(max)";
|
||||
case VARBINARY:
|
||||
case LONG32VARBINARY:
|
||||
case BLOB:
|
||||
return "varbinary(max)";
|
||||
}
|
||||
return super.castType( sqlTypeCode );
|
||||
return switch (sqlTypeCode) {
|
||||
case VARCHAR, LONG32VARCHAR, CLOB -> "varchar(max)";
|
||||
case NVARCHAR, LONG32NVARCHAR, NCLOB -> "nvarchar(max)";
|
||||
case VARBINARY, LONG32VARBINARY, BLOB -> "varbinary(max)";
|
||||
default -> super.castType( sqlTypeCode );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -299,10 +274,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
JdbcTypeRegistry jdbcTypeRegistry) {
|
||||
switch ( jdbcTypeCode ) {
|
||||
case OTHER:
|
||||
switch ( columnTypeName ) {
|
||||
case "uniqueidentifier":
|
||||
jdbcTypeCode = UUID;
|
||||
break;
|
||||
if ( columnTypeName.equals("uniqueidentifier") ) {
|
||||
jdbcTypeCode = UUID;
|
||||
}
|
||||
break;
|
||||
case GEOMETRY_TYPE_CODE:
|
||||
|
@ -463,21 +436,11 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
@Override
|
||||
public String trimPattern(TrimSpec specification, boolean isWhitespace) {
|
||||
if ( getVersion().isSameOrAfter( 16 ) ) {
|
||||
switch ( specification ) {
|
||||
case BOTH:
|
||||
return isWhitespace
|
||||
? "trim(?1)"
|
||||
: "trim(?2 from ?1)";
|
||||
case LEADING:
|
||||
return isWhitespace
|
||||
? "ltrim(?1)"
|
||||
: "ltrim(?1,?2)";
|
||||
case TRAILING:
|
||||
return isWhitespace
|
||||
? "rtrim(?1)"
|
||||
: "rtrim(?1,?2)";
|
||||
}
|
||||
throw new UnsupportedOperationException( "Unsupported specification: " + specification );
|
||||
return switch (specification) {
|
||||
case BOTH -> isWhitespace ? "trim(?1)" : "trim(?2 from ?1)";
|
||||
case LEADING -> isWhitespace ? "ltrim(?1)" : "ltrim(?1,?2)";
|
||||
case TRAILING -> isWhitespace ? "rtrim(?1)" : "rtrim(?1,?2)";
|
||||
};
|
||||
}
|
||||
return super.trimPattern( specification, isWhitespace );
|
||||
}
|
||||
|
@ -520,8 +483,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IdentifierHelper buildIdentifierHelper(
|
||||
IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData) throws SQLException {
|
||||
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
|
||||
throws SQLException {
|
||||
|
||||
if ( dbMetaData == null ) {
|
||||
// TODO: if DatabaseMetaData != null, unquoted case strategy is set to IdentifierCaseStrategy.UPPER
|
||||
|
@ -580,18 +543,12 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
if ( getVersion().isSameOrAfter( 16 ) ) {
|
||||
return true;
|
||||
}
|
||||
return super.supportsIfExistsBeforeTableName();
|
||||
return getVersion().isSameOrAfter( 16 ) || super.supportsIfExistsBeforeTableName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeConstraintName() {
|
||||
if ( getVersion().isSameOrAfter( 16 ) ) {
|
||||
return true;
|
||||
}
|
||||
return super.supportsIfExistsBeforeConstraintName();
|
||||
return getVersion().isSameOrAfter( 16 ) || super.supportsIfExistsBeforeConstraintName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -602,7 +559,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
@Override
|
||||
public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
LockMode lockMode = lockOptions.getAliasSpecificLockMode( tableName );
|
||||
if (lockMode == null) {
|
||||
if ( lockMode == null ) {
|
||||
lockMode = lockOptions.getLockMode();
|
||||
}
|
||||
|
||||
|
@ -612,19 +569,14 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
final String noWaitStr = lockOptions.getTimeOut() == LockOptions.NO_WAIT ? ",nowait" : "";
|
||||
final String skipLockStr = lockOptions.getTimeOut() == LockOptions.SKIP_LOCKED ? ",readpast" : "";
|
||||
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_WRITE:
|
||||
case WRITE:
|
||||
return tableName + " with (" + writeLockStr + ",rowlock" + noWaitStr + skipLockStr + ")";
|
||||
case PESSIMISTIC_READ:
|
||||
return tableName + " with (" + readLockStr + ",rowlock" + noWaitStr + skipLockStr + ")";
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
return tableName + " with (updlock,rowlock,readpast" + noWaitStr + ")";
|
||||
case UPGRADE_NOWAIT:
|
||||
return tableName + " with (updlock,holdlock,rowlock,nowait)";
|
||||
default:
|
||||
return tableName;
|
||||
}
|
||||
return switch (lockMode) {
|
||||
case PESSIMISTIC_WRITE, WRITE ->
|
||||
tableName + " with (" + writeLockStr + ",rowlock" + noWaitStr + skipLockStr + ")";
|
||||
case PESSIMISTIC_READ -> tableName + " with (" + readLockStr + ",rowlock" + noWaitStr + skipLockStr + ")";
|
||||
case UPGRADE_SKIPLOCKED -> tableName + " with (updlock,rowlock,readpast" + noWaitStr + ")";
|
||||
case UPGRADE_NOWAIT -> tableName + " with (updlock,holdlock,rowlock,nowait)";
|
||||
default -> tableName;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -704,12 +656,9 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public SequenceSupport getSequenceSupport() {
|
||||
if ( getVersion().isSameOrAfter( 16 ) ) {
|
||||
return SQLServer16SequenceSupport.INSTANCE;
|
||||
}
|
||||
else {
|
||||
return SQLServerSequenceSupport.INSTANCE;
|
||||
}
|
||||
return getVersion().isSameOrAfter( 16 )
|
||||
? SQLServer16SequenceSupport.INSTANCE
|
||||
: SQLServerSequenceSupport.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -720,9 +669,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public String getQueryHintString(String sql, String hints) {
|
||||
final StringBuilder buffer = new StringBuilder(
|
||||
sql.length() + hints.length() + 12
|
||||
);
|
||||
final StringBuilder buffer =
|
||||
new StringBuilder( sql.length() + hints.length() + 12 );
|
||||
final int pos = sql.indexOf( ';' );
|
||||
if ( pos > -1 ) {
|
||||
buffer.append( sql, 0, pos );
|
||||
|
@ -735,7 +683,6 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
buffer.append( ";" );
|
||||
}
|
||||
sql = buffer.toString();
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
@ -773,7 +720,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
|
||||
return new TemplatedViolatedConstraintNameExtractor(
|
||||
sqle -> {
|
||||
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
|
||||
switch ( extractErrorCode( sqle ) ) {
|
||||
case 2627:
|
||||
case 2601:
|
||||
String message = sqle.getMessage();
|
||||
|
@ -793,27 +740,22 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return (sqlException, message, sql) -> {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final String sqlState = extractSqlState( sqlException );
|
||||
if ( "HY008".equals( sqlState ) ) {
|
||||
return new QueryTimeoutException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
switch ( errorCode ) {
|
||||
case 1222:
|
||||
return new LockTimeoutException( message, sqlException, sql );
|
||||
case 2627:
|
||||
case 2601:
|
||||
return new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return switch ( extractErrorCode( sqlException ) ) {
|
||||
case 1222 -> new LockTimeoutException( message, sqlException, sql );
|
||||
case 2627, 2601 -> new ConstraintViolationException(
|
||||
message,
|
||||
sqlException,
|
||||
sql,
|
||||
ConstraintViolationException.ConstraintKind.UNIQUE,
|
||||
getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
|
||||
);
|
||||
default -> null;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -835,47 +777,38 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
switch (unit) {
|
||||
case TIMEZONE_HOUR:
|
||||
return "(datepart(tz,?2)/60)";
|
||||
case TIMEZONE_MINUTE:
|
||||
return "(datepart(tz,?2)%60)";
|
||||
//currently Dialect.extract() doesn't need
|
||||
//to handle NANOSECOND (might change that?)
|
||||
// case NANOSECOND:
|
||||
// //this should evaluate to a bigint type
|
||||
// return "(datepart(second,?2)*1000000000+datepart(nanosecond,?2))";
|
||||
case SECOND:
|
||||
return switch (unit) {
|
||||
case TIMEZONE_HOUR -> "(datepart(tz,?2)/60)";
|
||||
case TIMEZONE_MINUTE -> "(datepart(tz,?2)%60)";
|
||||
// currently Dialect.extract() doesn't need
|
||||
// to handle NANOSECOND (might change that?)
|
||||
// case NANOSECOND ->
|
||||
// // this should evaluate to a bigint type
|
||||
// "(datepart(second,?2)*1000000000+datepart(nanosecond,?2))";
|
||||
case SECOND ->
|
||||
//this should evaluate to a floating point type
|
||||
return "(datepart(second,?2)+datepart(nanosecond,?2)/1000000000)";
|
||||
case EPOCH:
|
||||
return "datediff_big(second, '1970-01-01', ?2)";
|
||||
default:
|
||||
return "datepart(?1,?2)";
|
||||
}
|
||||
"(datepart(second,?2)+datepart(nanosecond,?2)/1000000000)";
|
||||
case EPOCH -> "datediff_big(second, '1970-01-01', ?2)";
|
||||
default -> "datepart(?1,?2)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
// dateadd() supports only especially small magnitudes
|
||||
// since it casts its argument to int (and unfortunately
|
||||
// there's no dateadd_big()) so here we need to use two
|
||||
// calls to dateadd() to add a whole duration
|
||||
switch (unit) {
|
||||
case NANOSECOND: //use nanosecond as the "native" precision
|
||||
case NATIVE:
|
||||
return "dateadd(nanosecond,?2%1000000000,dateadd(second,?2/1000000000,?3))";
|
||||
// case NATIVE:
|
||||
// // we could in principle use 1/10th microsecond as the "native" precision
|
||||
// return "dateadd(nanosecond,?2%10000000,dateadd(second,?2/10000000,?3))";
|
||||
case SECOND:
|
||||
return "dateadd(nanosecond,cast(?2*1e9 as bigint)%1000000000,dateadd(second,?2,?3))";
|
||||
default:
|
||||
return "dateadd(?1,?2,?3)";
|
||||
}
|
||||
return switch (unit) { //use nanosecond as the "native" precision
|
||||
case NANOSECOND, NATIVE -> "dateadd(nanosecond,?2%1000000000,dateadd(second,?2/1000000000,?3))";
|
||||
// we could, in principle, use 1/10th microsecond as the "native" precision
|
||||
// case NATIVE -> "dateadd(nanosecond,?2%10000000,dateadd(second,?2/10000000,?3))";
|
||||
case SECOND -> "dateadd(nanosecond,cast(?2*1e9 as bigint)%1000000000,dateadd(second,?2,?3))";
|
||||
default -> "dateadd(?1,?2,?3)";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
if ( unit == TemporalUnit.NATIVE ) {
|
||||
//use nanosecond as the "native" precision
|
||||
|
@ -894,22 +827,19 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
@Override
|
||||
public String translateDurationField(TemporalUnit unit) {
|
||||
//use nanosecond as the "native" precision
|
||||
if ( unit == TemporalUnit.NATIVE ) {
|
||||
return "nanosecond";
|
||||
}
|
||||
else {
|
||||
return super.translateDurationField( unit );
|
||||
}
|
||||
return unit == TemporalUnit.NATIVE
|
||||
? "nanosecond"
|
||||
: super.translateDurationField( unit );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
return switch (unit) {
|
||||
//the ISO week number (behavior of "week" depends on a system property)
|
||||
case WEEK: return "isowk";
|
||||
case OFFSET: return "tz";
|
||||
default: return super.translateExtractField(unit);
|
||||
}
|
||||
case WEEK -> "isowk";
|
||||
case OFFSET -> "tz";
|
||||
default -> super.translateExtractField( unit );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -955,12 +885,6 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
.replace("x", "zz");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "0x" );
|
||||
PrimitiveByteArrayJavaType.INSTANCE.appendString( appender, bytes );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendUUIDLiteral(SqlAppender appender, java.util.UUID literal) {
|
||||
appender.appendSql( "cast('" );
|
||||
|
@ -972,6 +896,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -1004,7 +929,12 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "cast('" );
|
||||
|
@ -1031,6 +961,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -1057,25 +988,18 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public String getCreateTemporaryTableColumnAnnotation(int sqlTypeCode) {
|
||||
switch (sqlTypeCode) {
|
||||
case Types.CHAR:
|
||||
case Types.NCHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.NVARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.LONGNVARCHAR:
|
||||
return "collate database_default";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return switch (sqlTypeCode) {
|
||||
case Types.CHAR, Types.NCHAR, Types.VARCHAR, Types.NVARCHAR, Types.LONGVARCHAR, Types.LONGNVARCHAR ->
|
||||
"collate database_default";
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDropSchemaCommand(String schemaName) {
|
||||
if ( getVersion().isSameOrAfter( 13 ) ) {
|
||||
return new String[] { "drop schema if exists " + schemaName };
|
||||
}
|
||||
return super.getDropSchemaCommand( schemaName );
|
||||
return getVersion().isSameOrAfter( 13 )
|
||||
? new String[] { "drop schema if exists " + schemaName }
|
||||
: super.getDropSchemaCommand( schemaName );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1087,11 +1011,11 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public String getCreateIndexTail(boolean unique, List<Column> columns) {
|
||||
if (unique) {
|
||||
StringBuilder tail = new StringBuilder();
|
||||
if ( unique ) {
|
||||
final StringBuilder tail = new StringBuilder();
|
||||
for ( Column column : columns ) {
|
||||
if ( column.isNullable() ) {
|
||||
tail.append( tail.length() == 0 ? " where " : " and " )
|
||||
tail.append( tail.isEmpty() ? " where " : " and " )
|
||||
.append( column.getQuotedName( this ) )
|
||||
.append( " is not null" );
|
||||
}
|
||||
|
@ -1125,10 +1049,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public Exporter<Sequence> getSequenceExporter() {
|
||||
if ( exporter == null ) {
|
||||
return super.getSequenceExporter();
|
||||
}
|
||||
return exporter;
|
||||
return exporter == null ? super.getSequenceExporter() : exporter;
|
||||
}
|
||||
|
||||
private static class SqlServerSequenceExporter extends StandardSequenceExporter {
|
||||
|
@ -1176,7 +1097,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
EntityMutationTarget mutationTarget,
|
||||
OptionalTableUpdate optionalTableUpdate,
|
||||
SessionFactoryImplementor factory) {
|
||||
final SQLServerSqlAstTranslator<JdbcOperation> translator = new SQLServerSqlAstTranslator<>( factory, optionalTableUpdate );
|
||||
final SQLServerSqlAstTranslator<JdbcOperation> translator =
|
||||
new SQLServerSqlAstTranslator<>( factory, optionalTableUpdate );
|
||||
return translator.createMergeOperation( optionalTableUpdate );
|
||||
}
|
||||
|
||||
|
@ -1199,16 +1121,13 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
public String getCheckConstraintString(CheckConstraint checkConstraint) {
|
||||
final String constraintName = checkConstraint.getName();
|
||||
return constraintName == null
|
||||
?
|
||||
" check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")"
|
||||
:
|
||||
" constraint " + constraintName + " check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")";
|
||||
? " check " + getCheckConstraintOptions( checkConstraint )
|
||||
+ "(" + checkConstraint.getConstraint() + ")"
|
||||
: " constraint " + constraintName + " check " + getCheckConstraintOptions( checkConstraint )
|
||||
+ "(" + checkConstraint.getConstraint() + ")";
|
||||
}
|
||||
|
||||
private String getCheckConstraintOptions(CheckConstraint checkConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return checkConstraint.getOptions() + " ";
|
||||
}
|
||||
return "";
|
||||
return isNotEmpty( checkConstraint.getOptions() ) ? checkConstraint.getOptions() + " " : "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,14 +148,10 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
int scale,
|
||||
int displaySize) {
|
||||
// Sybase jconnect driver reports the "actual" precision in the display size
|
||||
switch ( jdbcTypeCode ) {
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.REAL:
|
||||
case Types.DOUBLE:
|
||||
return displaySize;
|
||||
}
|
||||
return super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize );
|
||||
return switch (jdbcTypeCode) {
|
||||
case Types.CHAR, Types.VARCHAR, Types.REAL, Types.DOUBLE -> displaySize;
|
||||
default -> super.resolveSqlTypeLength( columnTypeName, jdbcTypeCode, precision, scale, displaySize );
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -265,7 +261,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
|
||||
super.initializeFunctionRegistry(functionContributions);
|
||||
super.initializeFunctionRegistry( functionContributions );
|
||||
|
||||
CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions);
|
||||
|
||||
|
@ -355,6 +351,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -379,7 +376,12 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Date date,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( "convert(date,'" );
|
||||
|
@ -405,6 +407,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
@SuppressWarnings("deprecation")
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
|
@ -430,21 +433,17 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
case WEEK: return "calweekofyear"; //the ISO week number I think
|
||||
default: return super.translateExtractField(unit);
|
||||
}
|
||||
return switch (unit) {
|
||||
case WEEK -> "calweekofyear"; // the ISO week number I think
|
||||
default -> super.translateExtractField(unit);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String extractPattern(TemporalUnit unit) {
|
||||
if ( unit == TemporalUnit.EPOCH ) {
|
||||
return "datediff(second, '1970-01-01 00:00:00', ?2)";
|
||||
}
|
||||
else {
|
||||
//TODO!!
|
||||
return "datepart(?1,?2)";
|
||||
}
|
||||
return unit == TemporalUnit.EPOCH
|
||||
? "datediff(second, '1970-01-01 00:00:00', ?2)"
|
||||
: "datepart(?1,?2)"; //TODO!
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -452,13 +451,13 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
//TODO!!
|
||||
return "dateadd(?1,?2,?3)";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
|
||||
//TODO!!
|
||||
return "datediff(?1,?2,?3)";
|
||||
|
@ -477,7 +476,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
@Override
|
||||
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
|
||||
throws SQLException {
|
||||
// Default to MIXED because the jconn driver doesn't seem to report anything useful
|
||||
// Default to MIXED because the jconnect driver doesn't seem to report anything useful
|
||||
builder.setUnquotedCaseStrategy( IdentifierCaseStrategy.MIXED );
|
||||
if ( dbMetaData == null ) {
|
||||
builder.setQuotedCaseStrategy( IdentifierCaseStrategy.MIXED );
|
||||
|
@ -498,9 +497,9 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
@Override
|
||||
public CallableStatementSupport getCallableStatementSupport() {
|
||||
return driverKind == SybaseDriverKind.JTDS ?
|
||||
JTDSCallableStatementSupport.INSTANCE :
|
||||
SybaseCallableStatementSupport.INSTANCE;
|
||||
return driverKind == SybaseDriverKind.JTDS
|
||||
? JTDSCallableStatementSupport.INSTANCE
|
||||
: SybaseCallableStatementSupport.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -182,12 +182,11 @@ public class TiDBDialect extends MySQLDialect {
|
|||
return FunctionalDependencyAnalysisSupportImpl.TABLE_REFERENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
|
||||
if ( unit == TemporalUnit.SECOND && intervalType == null ) {
|
||||
// TiDB doesn't natively support adding fractional seconds
|
||||
return "timestampadd(microsecond,?2*1e6,?3)";
|
||||
}
|
||||
return super.timestampaddPattern( unit, temporalType, intervalType );
|
||||
// TiDB doesn't natively support adding fractional seconds
|
||||
return unit == TemporalUnit.SECOND && intervalType == null
|
||||
? "timestampadd(microsecond,?2*1e6,?3)"
|
||||
: super.timestampaddPattern(unit, temporalType, intervalType);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue