Skip to content

Commit 90f7ed9

Browse files
committed
Add HQL support for JDBC literals.
Closes #3739
1 parent dcf4991 commit 90f7ed9

File tree

4 files changed

+581
-51
lines changed

4 files changed

+581
-51
lines changed

spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4

+170-22
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,10 @@ literal
314314
| NULL
315315
| booleanLiteral
316316
| numericLiteral
317-
| dateTimeLiteral
318317
| binaryLiteral
318+
| temporalLiteral
319+
| arrayLiteral
320+
| generalizedLiteral
319321
;
320322

321323
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-boolean-literals
@@ -326,30 +328,157 @@ booleanLiteral
326328

327329
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-numeric-literals
328330
numericLiteral
329-
: INTEGER_LITERAL
330-
| LONG_LITERAL
331-
| BIG_INTEGER_LITERAL
332-
| FLOAT_LITERAL
333-
| DOUBLE_LITERAL
334-
| BIG_DECIMAL_LITERAL
335-
| HEX_LITERAL
336-
;
331+
: INTEGER_LITERAL
332+
| LONG_LITERAL
333+
| BIG_INTEGER_LITERAL
334+
| FLOAT_LITERAL
335+
| DOUBLE_LITERAL
336+
| BIG_DECIMAL_LITERAL
337+
| HEX_LITERAL
338+
;
337339

338340
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-datetime-literals
341+
/**
342+
* A literal datetime, in braces, or with the 'datetime' keyword
343+
*/
339344
dateTimeLiteral
340-
: LOCAL_DATE
341-
| LOCAL_TIME
342-
| LOCAL_DATETIME
343-
| CURRENT_DATE
344-
| CURRENT_TIME
345-
| CURRENT_TIMESTAMP
346-
| OFFSET_DATETIME
347-
| (LOCAL | CURRENT) DATE
348-
| (LOCAL | CURRENT) TIME
349-
| (LOCAL | CURRENT | OFFSET) DATETIME
350-
| INSTANT
345+
: localDateTimeLiteral
346+
| zonedDateTimeLiteral
347+
| offsetDateTimeLiteral
348+
;
349+
350+
localDateTimeLiteral
351+
: '(' localDateTime ')'
352+
| LOCAL? DATETIME localDateTime
353+
;
354+
355+
zonedDateTimeLiteral
356+
: '(' zonedDateTime ')'
357+
| ZONED? DATETIME zonedDateTime
358+
;
359+
360+
offsetDateTimeLiteral
361+
: '(' offsetDateTime ')'
362+
| OFFSET? DATETIME offsetDateTimeWithMinutes
363+
;
364+
/**
365+
* A literal date, in braces, or with the 'date' keyword
366+
*/
367+
dateLiteral
368+
: '(' date ')'
369+
| LOCAL? DATE date
351370
;
352371

372+
/**
373+
* A literal time, in braces, or with the 'time' keyword
374+
*/
375+
timeLiteral
376+
: '(' time ')'
377+
| LOCAL? TIME time
378+
;
379+
380+
/**
381+
* A literal datetime
382+
*/
383+
dateTime
384+
: localDateTime
385+
| zonedDateTime
386+
| offsetDateTime
387+
;
388+
389+
localDateTime
390+
: date time
391+
;
392+
393+
zonedDateTime
394+
: date time zoneId
395+
;
396+
397+
offsetDateTime
398+
: date time offset
399+
;
400+
401+
offsetDateTimeWithMinutes
402+
: date time offsetWithMinutes
403+
;
404+
405+
/**
406+
* A JDBC-style timestamp escape, as required by JPQL
407+
*/
408+
jdbcTimestampLiteral
409+
: TIMESTAMP_ESCAPE_START (dateTime | genericTemporalLiteralText) '}'
410+
;
411+
412+
/**
413+
* A JDBC-style date escape, as required by JPQL
414+
*/
415+
jdbcDateLiteral
416+
: DATE_ESCAPE_START (date | genericTemporalLiteralText) '}'
417+
;
418+
419+
/**
420+
* A JDBC-style time escape, as required by JPQL
421+
*/
422+
jdbcTimeLiteral
423+
: TIME_ESCAPE_START (time | genericTemporalLiteralText) '}'
424+
;
425+
426+
genericTemporalLiteralText
427+
: STRING_LITERAL
428+
;
429+
430+
/**
431+
* A generic format for specifying literal values of arbitary types
432+
*/
433+
arrayLiteral
434+
: '[' (expression (',' expression)*)? ']'
435+
;
436+
437+
/**
438+
* A generic format for specifying literal values of arbitary types
439+
*/
440+
generalizedLiteral
441+
: '(' generalizedLiteralType ':' generalizedLiteralText ')'
442+
;
443+
444+
generalizedLiteralType : STRING_LITERAL;
445+
generalizedLiteralText : STRING_LITERAL;
446+
447+
/**
448+
* A literal date
449+
*/
450+
date
451+
: year '-' month '-' day
452+
;
453+
454+
/**
455+
* A literal time
456+
*/
457+
time
458+
: hour ':' minute (':' second)?
459+
;
460+
461+
/**
462+
* A literal offset
463+
*/
464+
offset
465+
: (PLUS | MINUS) hour (':' minute)?
466+
;
467+
468+
offsetWithMinutes
469+
: (PLUS | MINUS) hour ':' minute
470+
;
471+
472+
year: INTEGER_LITERAL;
473+
month: INTEGER_LITERAL;
474+
day: INTEGER_LITERAL;
475+
hour: INTEGER_LITERAL;
476+
minute: INTEGER_LITERAL;
477+
second: INTEGER_LITERAL | DOUBLE_LITERAL;
478+
zoneId
479+
: IDENTIFIER ('/' IDENTIFIER)?
480+
| STRING_LITERAL;
481+
353482
/**
354483
* A field that may be extracted from a date, time, or datetime
355484
*/
@@ -402,8 +531,17 @@ binaryLiteral
402531
| '{' HEX_LITERAL (',' HEX_LITERAL)* '}'
403532
;
404533

405-
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-enum-literals
406-
// TBD
534+
/**
535+
* A literal date, time, or datetime, in HQL syntax, or as a JDBC-style "escape" syntax
536+
*/
537+
temporalLiteral
538+
: dateTimeLiteral
539+
| dateLiteral
540+
| timeLiteral
541+
| jdbcTimestampLiteral
542+
| jdbcDateLiteral
543+
| jdbcTimeLiteral
544+
;
407545

408546
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-java-constants
409547
// TBD
@@ -1685,6 +1823,16 @@ BINARY_LITERAL : [xX] '\'' HEX_DIGIT+ '\''
16851823
| [xX] '"' HEX_DIGIT+ '"'
16861824
;
16871825

1826+
// ESCAPE start tokens
1827+
TIMESTAMP_ESCAPE_START : '{ts';
1828+
DATE_ESCAPE_START : '{d';
1829+
TIME_ESCAPE_START : '{t';
1830+
1831+
PLUS : '+';
1832+
MINUS : '-';
1833+
1834+
1835+
16881836
fragment
16891837
LETTER : [a-zA-Z\u0080-\ufffe_$];
16901838

0 commit comments

Comments
 (0)