warning cleanups in Dialects

This commit is contained in:
Gavin King 2024-09-09 01:14:55 +02:00
parent 47f9bcfb24
commit fc9229e9f4
14 changed files with 902 additions and 1359 deletions

View File

@ -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

View File

@ -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;
};
};
}

View File

@ -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)";

View File

@ -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 );

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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() + " " : "";
}
}

View File

@ -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

View File

@ -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);
}
}