mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-18 00:55:16 +00:00
use custom-rendered datetime literals on MySQL instead of JDBC escapes
This commit is contained in:
parent
2aece6fb95
commit
4a87bc4bb8
@ -11,6 +11,11 @@
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
@ -104,6 +109,11 @@
|
|||||||
import static org.hibernate.type.SqlTypes.TINYINT;
|
import static org.hibernate.type.SqlTypes.TINYINT;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithNanos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@linkplain Dialect SQL dialect} for MySQL 5.7 and above.
|
* A {@linkplain Dialect SQL dialect} for MySQL 5.7 and above.
|
||||||
@ -765,6 +775,91 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsTemporalLiteralOffset() {
|
||||||
|
return getMySQLVersion().isSameOrAfter(8,0,19);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
TemporalAccessor temporalAccessor,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, temporalAccessor );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
if ( temporalAccessor instanceof ZonedDateTime ) {
|
||||||
|
temporalAccessor = ((ZonedDateTime) temporalAccessor).toOffsetDateTime();
|
||||||
|
}
|
||||||
|
appender.appendSql( "timestamp '" );
|
||||||
|
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone, false );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, date );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, date );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp '" );
|
||||||
|
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
Calendar calendar,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, calendar );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, calendar );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp '" );
|
||||||
|
appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsUnionAll() {
|
public boolean supportsUnionAll() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -47,6 +47,7 @@ private DateTimeUtils() {
|
|||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "XXX";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "XXX";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "XXX";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "XXX";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_NANOS + "XXX";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_NANOS + "XXX";
|
||||||
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET_NOZ = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "xxx";
|
||||||
|
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH );
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH );
|
||||||
@ -71,6 +72,10 @@ private DateTimeUtils() {
|
|||||||
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET,
|
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET,
|
||||||
Locale.ENGLISH
|
Locale.ENGLISH
|
||||||
);
|
);
|
||||||
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET_NOZ = DateTimeFormatter.ofPattern(
|
||||||
|
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET_NOZ,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
||||||
FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET,
|
FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET,
|
||||||
Locale.ENGLISH
|
Locale.ENGLISH
|
||||||
@ -99,15 +104,14 @@ private DateTimeUtils() {
|
|||||||
.optionalStart().appendZoneOrOffsetId().optionalEnd()
|
.optionalStart().appendZoneOrOffsetId().optionalEnd()
|
||||||
.toFormatter();
|
.toFormatter();
|
||||||
|
|
||||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH ) );
|
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT =
|
||||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
|
ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH ) );
|
||||||
private static final ThreadLocal<SimpleDateFormat> TIME_WITH_OFFSET_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH ) );
|
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT =
|
||||||
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial(
|
ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
|
||||||
() -> new SimpleDateFormat(
|
private static final ThreadLocal<SimpleDateFormat> TIME_WITH_OFFSET_FORMAT =
|
||||||
FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
|
ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH ) );
|
||||||
Locale.ENGLISH
|
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT =
|
||||||
)
|
ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIMESTAMP_WITH_MILLIS, Locale.ENGLISH ) );
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pattern used for parsing literal offset datetimes in HQL.
|
* Pattern used for parsing literal offset datetimes in HQL.
|
||||||
@ -156,6 +160,24 @@ public static void appendAsTimestampWithMicros(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void appendAsTimestampWithMicros(
|
||||||
|
SqlAppender appender,
|
||||||
|
TemporalAccessor temporalAccessor,
|
||||||
|
boolean supportsOffset,
|
||||||
|
TimeZone jdbcTimeZone,
|
||||||
|
boolean allowZforZeroOffset) {
|
||||||
|
appendAsTimestamp(
|
||||||
|
appender,
|
||||||
|
temporalAccessor,
|
||||||
|
supportsOffset,
|
||||||
|
jdbcTimeZone,
|
||||||
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS,
|
||||||
|
allowZforZeroOffset
|
||||||
|
? DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET
|
||||||
|
: DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET_NOZ
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static void appendAsTimestampWithMillis(
|
public static void appendAsTimestampWithMillis(
|
||||||
SqlAppender appender,
|
SqlAppender appender,
|
||||||
TemporalAccessor temporalAccessor,
|
TemporalAccessor temporalAccessor,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user