Properly handle EXTRACT function in HQL.

HQL's extract function supports things like "day of week", "day of month", and "week of year". Extend support to these alternate expressions.

See #3219.
This commit is contained in:
Greg L. Turnquist
2023-11-06 10:47:01 -06:00
parent 018c2acd86
commit 0aa5be8ba2
3 changed files with 71 additions and 1 deletions

View File

@@ -382,6 +382,9 @@ expression
| expression op=('*' | '/') expression # MultiplicationExpression
| expression op=('+' | '-') expression # AdditionExpression
| expression '||' expression # HqlConcatenationExpression
| DAY OF WEEK # DayOfWeekExpression
| DAY OF MONTH # DayOfMonthExpression
| WEEK OF YEAR # WeekOfYearExpression
;
primaryExpression

View File

@@ -1223,6 +1223,42 @@ class HqlQueryRenderer extends HqlBaseVisitor<List<JpaQueryParsingToken>> {
return tokens;
}
@Override
public List<JpaQueryParsingToken> visitDayOfWeekExpression(HqlParser.DayOfWeekExpressionContext ctx) {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
tokens.add(new JpaQueryParsingToken(ctx.DAY()));
tokens.add(new JpaQueryParsingToken(ctx.OF()));
tokens.add(new JpaQueryParsingToken(ctx.WEEK()));
return tokens;
}
@Override
public List<JpaQueryParsingToken> visitDayOfMonthExpression(HqlParser.DayOfMonthExpressionContext ctx) {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
tokens.add(new JpaQueryParsingToken(ctx.DAY()));
tokens.add(new JpaQueryParsingToken(ctx.OF()));
tokens.add(new JpaQueryParsingToken(ctx.MONTH()));
return tokens;
}
@Override
public List<JpaQueryParsingToken> visitWeekOfYearExpression(HqlParser.WeekOfYearExpressionContext ctx) {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
tokens.add(new JpaQueryParsingToken(ctx.WEEK()));
tokens.add(new JpaQueryParsingToken(ctx.OF()));
tokens.add(new JpaQueryParsingToken(ctx.YEAR()));
return tokens;
}
@Override
public List<JpaQueryParsingToken> visitGroupedExpression(HqlParser.GroupedExpressionContext ctx) {
@@ -1915,11 +1951,12 @@ class HqlQueryRenderer extends HqlBaseVisitor<List<JpaQueryParsingToken>> {
if (ctx.EXTRACT() != null) {
tokens.add(new JpaQueryParsingToken(ctx.EXTRACT()));
tokens.add(new JpaQueryParsingToken(ctx.EXTRACT(), false));
tokens.add(TOKEN_OPEN_PAREN);
tokens.addAll(visit(ctx.expression(0)));
tokens.add(new JpaQueryParsingToken(ctx.FROM()));
tokens.addAll(visit(ctx.expression(1)));
NOSPACE(tokens);
tokens.add(TOKEN_CLOSE_PAREN);
} else if (ctx.dateTimeFunction() != null) {

View File

@@ -1605,4 +1605,34 @@ class HqlQueryRendererTests {
void powerShouldBeLegalInAQuery() {
assertQuery("select e.power.id from MyEntity e");
}
@Test // GH-3219
void extractFunctionShouldSupportAdditionalExtensions() {
assertQuery("""
select extract(day of week from departureTime) AS day, sum(duration) as duration from JourneyEntity
group by extract(day of week from departureTime)
""");
assertQuery("""
select extract(day of month from departureTime) AS day, sum(duration) as duration from JourneyEntity
group by extract(day of month from departureTime)
""");
assertQuery("""
select extract(week of year from departureTime) AS day, sum(duration) as duration from JourneyEntity
group by extract(week of year from departureTime)
""");
assertQuery("""
select extract(date from departureTime) AS date
group by extract(date from departureTime)
""");
assertQuery("""
select extract(time from departureTime) AS time
group by extract(time from departureTime)
""");
assertQuery("""
select extract(epoch from departureTime) AS epoch
group by extract(epoch from departureTime)
""");
}
}