Skip to content

Commit

Permalink
HHH-11773 - Add support for JDBC 4.2 type names
Browse files Browse the repository at this point in the history
  • Loading branch information
marschall authored and vladmihalcea committed Jun 21, 2017
1 parent 7362a49 commit 33f05fe
Show file tree
Hide file tree
Showing 35 changed files with 985 additions and 3 deletions.
36 changes: 36 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
Expand Up @@ -196,7 +196,9 @@ protected Dialect() {

registerColumnType( Types.DATE, "date" );
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIME_WITH_TIMEZONE, getTimeWithTimeZone() );
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, getTimestampWithTimeZone() );

registerColumnType( Types.VARBINARY, "bit varying($l)" );
registerColumnType( Types.LONGVARBINARY, "bit varying($l)" );
Expand Down Expand Up @@ -2729,6 +2731,40 @@ public boolean useFollowOnLocking(QueryParameters parameters) {
public String getNotExpression(String expression) {
return "not " + expression;
}

/**
* Gets the name of the {@code TIME WITH TIME ZONE} type for this
* dialect.
* <p>
* If the dialect supports {@code TIME WITH TIME ZONE} this method
* should return the name of that type. If the dialect does not
* support {@code TIME WITH TIME ZONE} it should return the name of
* the {@code TIME} type.
* <p>
* Defaults to {@code "time"}.
*
* @return the type name
*/
protected String getTimeWithTimeZone() {
return "time";
}

/**
* Gets the name of the {@code TIMESTAMP WITH TIME ZONE} type for this
* dialect.
* <p>
* If the dialect supports {@code TIMESTAMP WITH TIME ZONE} this method
* should return the name of that type. If the dialect does not
* support {@code TIMESTAMP WITH TIME ZONE} it should return the name of
* the {@code TIMESTAMP} type.
* <p>
* Defaults to {@code "timestamp"}.
*
* @return the type name
*/
protected String getTimestampWithTimeZone() {
return "timestamp";
}

/**
* Get the UniqueDelegate supported by this dialect
Expand Down
22 changes: 22 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java
Expand Up @@ -73,6 +73,7 @@ public boolean bindLimitParametersInReverseOrder() {

private final String querySequenceString;
private final SequenceInformationExtractor sequenceInformationExtractor;
private final String timestampWithTimeZone;

/**
* Constructs a H2Dialect
Expand All @@ -82,6 +83,7 @@ public H2Dialect() {

String querySequenceString = "select sequence_name from information_schema.sequences";
SequenceInformationExtractor sequenceInformationExtractor = SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
String timestampWithTimeZone = "timestamp";
try {
// HHH-2300
final Class h2ConstantsClass = ReflectHelper.classForName( "org.h2.engine.Constants" );
Expand All @@ -95,6 +97,18 @@ public H2Dialect() {
if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
}
if ( majorVersion == 1 && minorVersion == 4 && buildId >= 192 && buildId <= 193 ) {
// 1.4.192 and 1.4.193 support only TIMESTAMP WITH TIMEZONE
// http://www.h2database.com/html/changelog.html
timestampWithTimeZone = "timestamp with timezone";
}
if ( ( majorVersion == 1 && minorVersion == 4 && buildId >= 194 )
|| ( majorVersion == 1 && minorVersion > 4 )
|| ( majorVersion > 1 ) ) {
// 1.4.194 and later support TIMESTAMP WITH TIME ZONE
// http://www.h2database.com/html/changelog.html
timestampWithTimeZone = "timestamp with time zone";
}
}
catch ( Exception e ) {
// probably H2 not in the classpath, though in certain app server environments it might just mean we are
Expand All @@ -104,6 +118,7 @@ public H2Dialect() {

this.querySequenceString = querySequenceString;
this.sequenceInformationExtractor = sequenceInformationExtractor;
this.timestampWithTimeZone = timestampWithTimeZone;

registerColumnType( Types.BOOLEAN, "boolean" );
registerColumnType( Types.BIGINT, "bigint" );
Expand All @@ -128,6 +143,8 @@ public H2Dialect() {
registerColumnType( Types.VARBINARY, "binary($l)" );
registerColumnType( Types.BLOB, "blob" );
registerColumnType( Types.CLOB, "clob" );
// when registration in superclass happens the instance variable is null
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, getTimestampWithTimeZone() );

// Aggregations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
registerFunction( "avg", new AvgWithArgumentCastFunction( "double" ) );
Expand Down Expand Up @@ -305,6 +322,11 @@ public SequenceInformationExtractor getSequenceInformationExtractor() {
return sequenceInformationExtractor;
}

@Override
protected String getTimestampWithTimeZone() {
return timestampWithTimeZone;
}

@Override
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
return EXTRACTER;
Expand Down
Expand Up @@ -106,6 +106,8 @@ public boolean bindLimitParametersFirst() {
*/
private int hsqldbVersion = 180;
private final LimitHandler limitHandler;
private final String timestampWithTimeZone;
private final String timeWithTimeZone;


/**
Expand Down Expand Up @@ -252,6 +254,20 @@ public HSQLDialect() {

// function templates
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) );

if ( hsqldbVersion >= 240 ) {
// starting with 2.4.0 TIMESTAMP WITH TIME ZONE and TIME WITH TIME ZONE are supported
timeWithTimeZone = "time with time zone";
timestampWithTimeZone = "timestamp with time zone";
}
else {
timeWithTimeZone = "time";
timestampWithTimeZone = "timestamp";
}

// when registration in superclass happens the instance variable is null
registerColumnType( Types.TIME_WITH_TIMEZONE, getTimeWithTimeZone() );
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, getTimestampWithTimeZone() );

getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );

Expand Down Expand Up @@ -571,6 +587,16 @@ public String getCurrentTimestampSQLFunctionName() {
return "current_timestamp";
}

@Override
protected String getTimeWithTimeZone() {
return timeWithTimeZone;
}

@Override
protected String getTimestampWithTimeZone() {
return timestampWithTimeZone;
}

/**
* For HSQLDB 2.0, this is a copy of the base class implementation.
* For HSQLDB 1.8, only READ_UNCOMMITTED is supported.
Expand Down
Expand Up @@ -272,6 +272,16 @@ public boolean isCurrentTimestampSelectStringCallable() {
public String getCurrentTimestampSelectString() {
return "select distinct current timestamp from informix.systables";
}

@Override
protected String getTimeWithTimeZone() {
return "datetime hour to second" ;
}

@Override
protected String getTimestampWithTimeZone() {
return "datetime year to fraction(5)";
}

@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
Expand Down
Expand Up @@ -219,6 +219,18 @@ public String getQuerySequencesString() {
public String getLowercaseFunction() {
return "lowercase";
}

@Override
protected String getTimeWithTimeZone() {
// http://wiki.ispirer.com/sqlways/ingres/data-types/time
return "time with time zone";
}

@Override
protected String getTimestampWithTimeZone() {
// http://wiki.ispirer.com/sqlways/ingres/data-types/timestamp
return "timestamp with time zone";
}

@Override
public LimitHandler getLimitHandler() {
Expand Down
Expand Up @@ -60,4 +60,9 @@ public MariaDB53Dialect() {
// from_unixtime(), timestamp() are functions that return TIMESTAMP that do not support a
// fractional seconds precision argument (so there's no need to override them here):
}

@Override
protected String getTimestampWithTimeZone() {
return "datetime(6)";
}
}
Expand Up @@ -73,4 +73,9 @@ public MySQL57Dialect() {
public boolean supportsRowValueConstructorSyntaxInInList() {
return true;
}

@Override
protected String getTimestampWithTimeZone() {
return "datetime(6)";
}
}
Expand Up @@ -75,4 +75,9 @@ public MySQL57InnoDBDialect() {
public boolean supportsRowValueConstructorSyntaxInInList() {
return true;
}

@Override
protected String getTimestampWithTimeZone() {
return "datetime(6)";
}
}
Expand Up @@ -566,6 +566,11 @@ public String getTableTypeString() {
return storageEngine.getTableTypeString( getEngineKeyword());
}

@Override
protected String getTimestampWithTimeZone() {
return "datetime";
}

protected String getEngineKeyword() {
return "type";
}
Expand Down
Expand Up @@ -291,6 +291,11 @@ public String getQuerySequencesString() {
public String getSelectGUIDString() {
return "select rawtohex(sys_guid()) from dual";
}

@Override
protected String getTimestampWithTimeZone() {
return "timestamp with time zone";
}

@Override
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
Expand Down
Expand Up @@ -163,6 +163,12 @@ public String getCurrentTimestampSQLFunctionName() {
public String getForUpdateString() {
return " for update";
}

@Override
protected String getTimestampWithTimeZone() {
// https://docs.oracle.com/cd/A91202_01/901_doc/server.901/a90120/ch2_feat.htm
return "timestamp with time zone";
}

@Override
public String getWriteLockString(int timeout) {
Expand Down
Expand Up @@ -605,6 +605,18 @@ public CallableStatementSupport getCallableStatementSupport() {
return PostgresCallableStatementSupport.INSTANCE;
}

@Override
protected String getTimeWithTimeZone() {
// https://www.postgresql.org/docs/9.1/static/datatype-datetime.html
return "time with time zone";
}

@Override
protected String getTimestampWithTimeZone() {
// https://www.postgresql.org/docs/9.1/static/datatype-datetime.html
return "timestamp with time zone";
}

@Override
public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
if ( position != 1 ) {
Expand Down
Expand Up @@ -61,4 +61,10 @@ public String renderOrderByElement(String expression, String collation, String o
public boolean supportsValuesList() {
return true;
}

@Override
protected String getTimestampWithTimeZone() {
// https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql
return "datetimeoffset";
}
}
Expand Up @@ -240,6 +240,18 @@ public String getSelectClauseNullString(int sqlType) {
public String getCreateMultisetTableString() {
return "create multiset table ";
}

@Override
protected String getTimeWithTimeZone() {
// www.info.teradata.com/download.cfm?ItemID=1003919
return "time with time zone";
}

@Override
protected String getTimestampWithTimeZone() {
// www.info.teradata.com/download.cfm?ItemID=1003919
return "timestamp with time zone";
}

@Override
public boolean supportsLobValueChangePropogation() {
Expand Down
Expand Up @@ -60,7 +60,9 @@ public BasicTypeRegistry() {

register( DateType.INSTANCE );
register( TimeType.INSTANCE );
register( TimeWithTimeZoneType.INSTANCE );
register( TimestampType.INSTANCE );
register( TimestampWithTimeZoneType.INSTANCE );
register( DbTimestampType.INSTANCE );
register( CalendarType.INSTANCE );
register( CalendarDateType.INSTANCE );
Expand Down
@@ -0,0 +1,49 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.type;

import java.sql.Time;
import java.time.OffsetTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import org.hibernate.dialect.Dialect;
import org.hibernate.type.descriptor.java.OffsetTimeJavaDescriptor;
import org.hibernate.type.descriptor.sql.TimeWithTimeZoneTypeDescriptor;

/**
* A type that maps between {@link java.sql.Types#TIME_WITH_TIMEZONE TIME_WITH_TIMEZONE} and {@link Time}
*
* @author Vlad Mihalcea
*/
public class TimeWithTimeZoneType
extends AbstractSingleColumnStandardBasicType<OffsetTime>
implements LiteralType<OffsetTime> {

public static final TimeWithTimeZoneType INSTANCE = new TimeWithTimeZoneType();

public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "HH:mm:ss.S xxxxx", Locale.ENGLISH );

public TimeWithTimeZoneType() {
super( TimeWithTimeZoneTypeDescriptor.INSTANCE, OffsetTimeJavaDescriptor.INSTANCE );
}

@Override
public String objectToSQLString(OffsetTime value, Dialect dialect) throws Exception {
return "{t '" + FORMATTER.format( value ) + "'}";
}

@Override
public String getName() {
return "time_with_timezone";
}

@Override
protected boolean registerUnderJavaType() {
return true;
}
}

0 comments on commit 33f05fe

Please sign in to comment.