fix an ambiguity in the grammar of datetime literals
this was my very stupid mistake
This commit is contained in:
parent
43cce5fe5e
commit
ae978b3d10
|
@ -304,6 +304,7 @@ WITH : [wW] [iI] [tT] [hH];
|
||||||
WITHIN : [wW] [iI] [tT] [hH] [iI] [nN];
|
WITHIN : [wW] [iI] [tT] [hH] [iI] [nN];
|
||||||
WITHOUT : [wW] [iI] [tT] [hH] [oO] [uU] [tT];
|
WITHOUT : [wW] [iI] [tT] [hH] [oO] [uU] [tT];
|
||||||
YEAR : [yY] [eE] [aA] [rR];
|
YEAR : [yY] [eE] [aA] [rR];
|
||||||
|
ZONED : [zZ] [oO] [nN] [eE] [dD];
|
||||||
|
|
||||||
// case-insensitive true, false and null recognition (split vote :)
|
// case-insensitive true, false and null recognition (split vote :)
|
||||||
TRUE : [tT] [rR] [uU] [eE];
|
TRUE : [tT] [rR] [uU] [eE];
|
||||||
|
|
|
@ -877,8 +877,24 @@ temporalLiteral
|
||||||
* A literal datetime, in braces, or with the 'datetime' keyword
|
* A literal datetime, in braces, or with the 'datetime' keyword
|
||||||
*/
|
*/
|
||||||
dateTimeLiteral
|
dateTimeLiteral
|
||||||
: LEFT_BRACE dateTime RIGHT_BRACE
|
: localDateTimeLiteral
|
||||||
| DATETIME dateTime
|
| zonedDateTimeLiteral
|
||||||
|
| offsetDateTimeLiteral
|
||||||
|
;
|
||||||
|
|
||||||
|
localDateTimeLiteral
|
||||||
|
: LEFT_BRACE localDateTime RIGHT_BRACE
|
||||||
|
| LOCAL? DATETIME localDateTime
|
||||||
|
;
|
||||||
|
|
||||||
|
zonedDateTimeLiteral
|
||||||
|
: LEFT_BRACE zonedDateTime RIGHT_BRACE
|
||||||
|
| ZONED? DATETIME zonedDateTime
|
||||||
|
;
|
||||||
|
|
||||||
|
offsetDateTimeLiteral
|
||||||
|
: LEFT_BRACE offsetDateTime RIGHT_BRACE
|
||||||
|
| OFFSET? DATETIME offsetDateTimeWithMinutes
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -900,8 +916,26 @@ timeLiteral
|
||||||
/**
|
/**
|
||||||
* A literal datetime
|
* A literal datetime
|
||||||
*/
|
*/
|
||||||
dateTime
|
dateTime
|
||||||
: date time (zoneId | offset)?
|
: localDateTime
|
||||||
|
| zonedDateTime
|
||||||
|
| offsetDateTime
|
||||||
|
;
|
||||||
|
|
||||||
|
localDateTime
|
||||||
|
: date time
|
||||||
|
;
|
||||||
|
|
||||||
|
zonedDateTime
|
||||||
|
: date time zoneId
|
||||||
|
;
|
||||||
|
|
||||||
|
offsetDateTime
|
||||||
|
: date time offset
|
||||||
|
;
|
||||||
|
|
||||||
|
offsetDateTimeWithMinutes
|
||||||
|
: date time offsetWithMinutes
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -925,6 +959,10 @@ offset
|
||||||
: (PLUS | MINUS) hour (COLON minute)?
|
: (PLUS | MINUS) hour (COLON minute)?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
offsetWithMinutes
|
||||||
|
: (PLUS | MINUS) hour COLON minute
|
||||||
|
;
|
||||||
|
|
||||||
year: INTEGER_LITERAL;
|
year: INTEGER_LITERAL;
|
||||||
month: INTEGER_LITERAL;
|
month: INTEGER_LITERAL;
|
||||||
day: INTEGER_LITERAL;
|
day: INTEGER_LITERAL;
|
||||||
|
@ -1174,19 +1212,19 @@ frameClause
|
||||||
*/
|
*/
|
||||||
frameStart
|
frameStart
|
||||||
: UNBOUNDED PRECEDING
|
: UNBOUNDED PRECEDING
|
||||||
| expression PRECEDING
|
| expression PRECEDING
|
||||||
| CURRENT ROW
|
| CURRENT ROW
|
||||||
| expression FOLLOWING
|
| expression FOLLOWING
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The end of the window content
|
* The end of the window content
|
||||||
*/
|
*/
|
||||||
frameEnd
|
frameEnd
|
||||||
: expression PRECEDING
|
: expression PRECEDING
|
||||||
| CURRENT ROW
|
| CURRENT ROW
|
||||||
| expression FOLLOWING
|
| expression FOLLOWING
|
||||||
| UNBOUNDED FOLLOWING
|
| UNBOUNDED FOLLOWING
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1194,9 +1232,9 @@ frameEnd
|
||||||
*/
|
*/
|
||||||
frameExclusion
|
frameExclusion
|
||||||
: EXCLUDE CURRENT ROW
|
: EXCLUDE CURRENT ROW
|
||||||
| EXCLUDE GROUP
|
| EXCLUDE GROUP
|
||||||
| EXCLUDE TIES
|
| EXCLUDE TIES
|
||||||
| EXCLUDE NO OTHERS
|
| EXCLUDE NO OTHERS
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3288,7 +3288,30 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDateTimeLiteral(HqlParser.DateTimeLiteralContext ctx) {
|
public Object visitDateTimeLiteral(HqlParser.DateTimeLiteralContext ctx) {
|
||||||
return ctx.getChild( 1 ).accept( this );
|
return ctx.getChild( 0 ).accept( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitLocalDateTimeLiteral(HqlParser.LocalDateTimeLiteralContext ctx) {
|
||||||
|
return ctx.localDateTime().accept( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitZonedDateTimeLiteral(HqlParser.ZonedDateTimeLiteralContext ctx) {
|
||||||
|
return ctx.zonedDateTime().accept( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitOffsetDateTimeLiteral(HqlParser.OffsetDateTimeLiteralContext ctx) {
|
||||||
|
if ( ctx.offsetDateTime() != null ) {
|
||||||
|
return ctx.offsetDateTime().accept(this);
|
||||||
|
}
|
||||||
|
else if ( ctx.offsetDateTimeWithMinutes() != null ) {
|
||||||
|
return ctx.offsetDateTimeWithMinutes().accept(this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3336,42 +3359,48 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDateTime(HqlParser.DateTimeContext ctx) {
|
public Object visitDateTime(HqlParser.DateTimeContext ctx) {
|
||||||
final ParseTree parseTree = ctx.getChild( 2 );
|
return ctx.getChild( 0 ).accept( this );
|
||||||
if ( parseTree instanceof HqlParser.ZoneIdContext || parseTree == null ) {
|
|
||||||
return dateTimeLiteralFrom(
|
|
||||||
(HqlParser.DateContext) ctx.getChild( 0 ),
|
|
||||||
(HqlParser.TimeContext) ctx.getChild( 1 ),
|
|
||||||
(HqlParser.ZoneIdContext) parseTree
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return offsetDatetimeLiteralFrom(
|
|
||||||
(HqlParser.DateContext) ctx.getChild( 0 ),
|
|
||||||
(HqlParser.TimeContext) ctx.getChild( 1 ),
|
|
||||||
(HqlParser.OffsetContext) parseTree
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SqmLiteral<?> dateTimeLiteralFrom(
|
@Override
|
||||||
|
public Object visitLocalDateTime(HqlParser.LocalDateTimeContext ctx) {
|
||||||
|
return localDateTimeLiteralFrom( ctx.date(), ctx.time() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitOffsetDateTime(HqlParser.OffsetDateTimeContext ctx) {
|
||||||
|
return offsetDatetimeLiteralFrom( ctx.date(), ctx.time(), ctx.offset() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitOffsetDateTimeWithMinutes(HqlParser.OffsetDateTimeWithMinutesContext ctx) {
|
||||||
|
return offsetDatetimeLiteralFrom( ctx.date(), ctx.time(), ctx.offsetWithMinutes() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitZonedDateTime(HqlParser.ZonedDateTimeContext ctx) {
|
||||||
|
return zonedDateTimeLiteralFrom( ctx.date(), ctx.time(), ctx.zoneId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqmLiteral<?> localDateTimeLiteralFrom(
|
||||||
|
HqlParser.DateContext date,
|
||||||
|
HqlParser.TimeContext time) {
|
||||||
|
return new SqmLiteral<>(
|
||||||
|
LocalDateTime.of( localDate( date ), localTime( time ) ),
|
||||||
|
resolveExpressibleTypeBasic( LocalDateTime.class ),
|
||||||
|
creationContext.getNodeBuilder()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqmLiteral<?> zonedDateTimeLiteralFrom(
|
||||||
HqlParser.DateContext date,
|
HqlParser.DateContext date,
|
||||||
HqlParser.TimeContext time,
|
HqlParser.TimeContext time,
|
||||||
HqlParser.ZoneIdContext timezone) {
|
HqlParser.ZoneIdContext timezone) {
|
||||||
if ( timezone == null ) {
|
return new SqmLiteral<>(
|
||||||
return new SqmLiteral<>(
|
ZonedDateTime.of( localDate( date ), localTime( time ), visitZoneId( timezone ) ),
|
||||||
LocalDateTime.of( localDate( date ), localTime( time ) ),
|
resolveExpressibleTypeBasic( ZonedDateTime.class ),
|
||||||
resolveExpressibleTypeBasic( LocalDateTime.class ),
|
creationContext.getNodeBuilder()
|
||||||
creationContext.getNodeBuilder()
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final ZoneId zoneId = visitZoneId( timezone );
|
|
||||||
return new SqmLiteral<>(
|
|
||||||
ZonedDateTime.of( localDate( date ), localTime( time ), zoneId ),
|
|
||||||
resolveExpressibleTypeBasic( ZonedDateTime.class ),
|
|
||||||
creationContext.getNodeBuilder()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3404,6 +3433,17 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SqmLiteral<?> offsetDatetimeLiteralFrom(
|
||||||
|
HqlParser.DateContext date,
|
||||||
|
HqlParser.TimeContext time,
|
||||||
|
HqlParser.OffsetWithMinutesContext offset) {
|
||||||
|
return new SqmLiteral<>(
|
||||||
|
OffsetDateTime.of( localDate( date ), localTime( time ), zoneOffset( offset ) ),
|
||||||
|
resolveExpressibleTypeBasic( OffsetDateTime.class ),
|
||||||
|
creationContext.getNodeBuilder()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDate(HqlParser.DateContext ctx) {
|
public Object visitDate(HqlParser.DateContext ctx) {
|
||||||
return new SqmLiteral<>(
|
return new SqmLiteral<>(
|
||||||
|
@ -3423,10 +3463,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalTime localTime(HqlParser.TimeContext ctx) {
|
private static LocalTime localTime(HqlParser.TimeContext ctx) {
|
||||||
final int hour = Integer.parseInt( ctx.getChild( 0 ).getText() );
|
final int hour = Integer.parseInt( ctx.hour().getText() );
|
||||||
final int minute = Integer.parseInt( ctx.getChild( 2 ).getText() );
|
final int minute = Integer.parseInt( ctx.minute().getText() );
|
||||||
if ( ctx.getChildCount() == 5 ) {
|
if ( ctx.second() != null ) {
|
||||||
final String secondText = ctx.getChild( 4 ).getText();
|
final String secondText = ctx.second().getText();
|
||||||
final int index = secondText.indexOf( '.');
|
final int index = secondText.indexOf( '.');
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
return LocalTime.of(
|
return LocalTime.of(
|
||||||
|
@ -3451,67 +3491,35 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
private static LocalDate localDate(HqlParser.DateContext ctx) {
|
private static LocalDate localDate(HqlParser.DateContext ctx) {
|
||||||
return LocalDate.of(
|
return LocalDate.of(
|
||||||
Integer.parseInt( ctx.getChild( 0 ).getText() ),
|
Integer.parseInt( ctx.year().getText() ),
|
||||||
Integer.parseInt( ctx.getChild( 2 ).getText() ),
|
Integer.parseInt( ctx.month().getText() ),
|
||||||
Integer.parseInt( ctx.getChild( 4 ).getText() )
|
Integer.parseInt( ctx.day().getText() )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ZoneOffset zoneOffset(HqlParser.OffsetContext offset) {
|
private static ZoneOffset zoneOffset(HqlParser.OffsetContext offset) {
|
||||||
final int factor = ( (TerminalNode) offset.getChild( 0 ) ).getSymbol().getType() == PLUS ? 1 : -1;
|
final int factor = ( (TerminalNode) offset.getChild( 0 ) ).getSymbol().getType() == PLUS ? 1 : -1;
|
||||||
final int hour = factor * Integer.parseInt( offset.getChild( 1 ).getText() );
|
final int hour = factor * Integer.parseInt( offset.hour().getText() );
|
||||||
if ( offset.getChildCount() == 2 ) {
|
if ( offset.getChildCount() == 2 ) {
|
||||||
return ZoneOffset.ofHours( hour );
|
return ZoneOffset.ofHours( hour );
|
||||||
}
|
}
|
||||||
return ZoneOffset.ofHoursMinutes(
|
return ZoneOffset.ofHoursMinutes(
|
||||||
hour,
|
hour,
|
||||||
factor * Integer.parseInt( offset.getChild( 3 ).getText() )
|
factor * Integer.parseInt( offset.minute().getText() )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// private SqmLiteral<OffsetDateTime> offsetDatetimeLiteralFrom(String literalText) {
|
private static ZoneOffset zoneOffset(HqlParser.OffsetWithMinutesContext offset) {
|
||||||
// TemporalAccessor parsed = OFFSET_DATE_TIME.parse( literalText );
|
final int factor = ( (TerminalNode) offset.getChild( 0 ) ).getSymbol().getType() == PLUS ? 1 : -1;
|
||||||
// return new SqmLiteral<>(
|
final int hour = factor * Integer.parseInt( offset.hour().getText() );
|
||||||
// OffsetDateTime.from( parsed ),
|
if ( offset.getChildCount() == 2 ) {
|
||||||
// resolveExpressibleTypeBasic( OffsetDateTime.class ),
|
return ZoneOffset.ofHours( hour );
|
||||||
// creationContext.getNodeBuilder()
|
}
|
||||||
// );
|
return ZoneOffset.ofHoursMinutes(
|
||||||
// }
|
hour,
|
||||||
//
|
factor * Integer.parseInt( offset.minute().getText() )
|
||||||
// private SqmLiteral<?> dateTimeLiteralFrom(String literalText) {
|
);
|
||||||
// //TO DO: return an OffsetDateTime when appropriate?
|
}
|
||||||
// TemporalAccessor parsed = DATE_TIME.parse( literalText );
|
|
||||||
// try {
|
|
||||||
// return new SqmLiteral<>(
|
|
||||||
// ZonedDateTime.from( parsed ),
|
|
||||||
// resolveExpressibleTypeBasic( ZonedDateTime.class ),
|
|
||||||
// creationContext.getNodeBuilder()
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// catch (DateTimeException dte) {
|
|
||||||
// return new SqmLiteral<>(
|
|
||||||
// LocalDateTime.from( parsed ),
|
|
||||||
// resolveExpressibleTypeBasic( LocalDateTime.class ),
|
|
||||||
// creationContext.getNodeBuilder()
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private SqmLiteral<LocalDate> localDateLiteralFrom(String literalText) {
|
|
||||||
// return new SqmLiteral<>(
|
|
||||||
// LocalDate.from( ISO_LOCAL_DATE.parse( literalText ) ),
|
|
||||||
// resolveExpressibleTypeBasic( LocalDate.class ),
|
|
||||||
// creationContext.getNodeBuilder()
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private SqmLiteral<LocalTime> localTimeLiteralFrom(String literalText) {
|
|
||||||
// return new SqmLiteral<>(
|
|
||||||
// LocalTime.from( ISO_LOCAL_TIME.parse( literalText ) ),
|
|
||||||
// resolveExpressibleTypeBasic( LocalTime.class ),
|
|
||||||
// creationContext.getNodeBuilder()
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
private SqmLiteral<?> sqlTimestampLiteralFrom(String literalText) {
|
private SqmLiteral<?> sqlTimestampLiteralFrom(String literalText) {
|
||||||
final TemporalAccessor parsed = DATE_TIME.parse( literalText.subSequence( 1, literalText.length() - 1 ) );
|
final TemporalAccessor parsed = DATE_TIME.parse( literalText.subSequence( 1, literalText.length() - 1 ) );
|
||||||
|
|
Loading…
Reference in New Issue