[hibernate-dev] 6.0 - HQL literals

Steve Ebersole steve at hibernate.org
Tue Jan 7 08:45:26 EST 2020


Thanks for the feedback.

I added some comments in-line.

On Tue, Jan 7, 2020 at 1:59 AM Yoann Rodiere <yoann at hibernate.org> wrote:

> Hi,
>
> The syntax looks nice.
> I suppose it's future-proof enough, though I can imagine us getting in
> trouble if JDBC starts allowing parameterized or custom formats, which may
> start with a digit or even (in edge cases) look like a date. That seems
> unlikely, so I think it's an acceptable risk.
>
> I'm not entirely sure allowing JDBC literals to be "passed-through" the
> HQL will always be intuitive, even if it's already allowed for integers:
> under some circumstances we map date-only or time-only types to timestamps,
> for example. The database might cast a date-only value to a timestamp
> automatically by setting hours/minutes/etc to zero, but I'm not sure that's
> what *we* do when persisting, considering the various hacks we have around
> timezones; '2019-01-01' might very well be converted to
> '2018-12-31T23:00:00', for all I know. As a result, there might be a broad
> range of Java types where these literals will be seen as "buggy".
>

Sorry, I should have been more clear.  The literals are not "passed
through"; it's just a mechanism to be able to recognize the literal
syntactically while parsing.  All of those forms I showed actually are
handled in the code and interpreted as a Java temporal.  We then do
whatever we want to do with it in order to send it to the database (often
even as a parameter).

As far as timezones, a datetime with no timezone is interpreted as a
LocalDateTime.  However I did have an open question there still regarding
*which* local - the local VM's timezone?  Or the "JDBC timezone" (which we
know via our `hibernate.jdbc.time_zone` setting)?  The literals can also
contain zone id or offset.  I choose to not except the form with 'T'.
E.g., all of these are valid:

   - {2020-01-01 10:10:10} - LocalDateTime
   - {2020-01-01 10:10:10 UTC} - ZonedDateTime
   - {2020-01-01 10:10:10 Z} - ZonedDateTime
   - {2020-01-01 10:10:10 +2} - ZonedDateTime
   - {2020-01-01 10:10:10 +02} - ZonedDateTime
   - {2020-01-01 10:10:10 +02:00} - ZonedDateTime
   - {2020-01-01 10:10:10 UTC+02:00} - ZonedDateTime
   - {2020-01-01 10:10:10 CST} - ZonedDateTime
   - {2020-01-01 10:10:10 America/Central} - ZonedDateTime
   - etc

* We also support a STRING_LITERAL form of temporal literals as I mentioned
originally.  In my experience, using
`java.time.format.DateTimeFormatter#parseBest` always returned a
ZonedDateTime whether a zone-id or offset was specified.  My understanding
is that this varies from Java 8 to Java 9.  So that's something to consider
as well.  I mention this because I tried to make interpreting the syntactic
form consistent.  If you are interested in the specifics of how this
happens, see:

   1. org.hibernate.query.hql.internal.SemanticQueryBuilder#interpretTemporalLiteral
   (handles syntactic forms)
   2. org.hibernate.type.descriptor.DateTimeUtils#DATE_TIME (handles String
   forms)


I don't understand the "broad range of Java types ..." part.  What do you
mean?  Do you have an example?


I might be wrong, but only exhaustive testing of all literals with all
> date/time types on all RDBMS will let us know for sure. Let's keep in mind
> how many bugs have surfaced from time-related features in the past...
>

Gavin actually did quite a bit of that in the PR he sent us.  He added
pretty cool support for various temporal-related things such as how to
handle formatting (to_char, etc), extraction and temporal arithmetic -
specifically formalizing and normalizing them across databases.


More information about the hibernate-dev mailing list