[#7793] Support DatePart.DAY_OF_YEAR

This commit is contained in:
Lukas Eder 2018-08-22 13:39:01 +02:00
parent 648cade2a6
commit f0ac0ea00c
4 changed files with 88 additions and 15 deletions

View File

@ -777,7 +777,21 @@ term =
truthValue = 'TRUE' | 'FALSE' | 'NULL'
;
datePart = 'YEAR' | 'MONTH' | 'DAY' | 'HOUR' | 'MINUTE' | 'SECOND' | 'ISO_DAY_OF_WEEK' | 'ISODOW' | 'DAY_OF_WEEK'
datePart =
( 'YEAR' | 'YYYY' | 'YY' )
| ( 'MONTH' | 'MM' | 'M' )
| ( 'DAY' | 'DD' | 'D' )
| ( 'HOUR' | 'HH' )
| ( 'MINUTE' | 'MI' | 'N' )
| ( 'SECOND' | 'SS' | 'S' )
| ( 'MILLISECOND' | 'MS' )
| ( 'MICROSECOND' | 'MCS' )
| ( 'NANOSECOND' | 'NS' )
| ( 'QUARTER' | 'QQ' | 'Q' )
| ( 'WEEK ' | 'WW' | 'WK' )
| ( 'ISO_DAY_OF_WEEK' | 'ISODOW' )
| ( 'DAY_OF_WEEK' | 'DAYOFWEEK' | 'WEEKDAY' | 'W' )
| ( 'DAY_OF_YEAR' | 'DAYOFYEAR' | 'DOY' | 'DY' | 'Y')
;
keep = 'KEEP' '(' 'DENSE_RANK' ( 'FIRST' | 'LAST' ) 'ORDER BY' sortFields ')'

View File

@ -14888,6 +14888,43 @@ public class DSL {
return extract(field, DatePart.ISO_DAY_OF_WEEK);
}
/**
* Get the day of week part of a date.
* <p>
* This is the same as calling {@link #extract(java.util.Date, DatePart)}
* with {@link DatePart#DAY_OF_YEAR}
*/
@Support({ H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
public static Field<Integer> dayOfYear(java.util.Date value) {
return extract(value, DatePart.DAY_OF_YEAR);
}
/**
* Get the day of week part of a date.
* <p>
* This is the same as calling {@link #extract(Temporal, DatePart)}
* with {@link DatePart#DAY_OF_YEAR}
*/
@Support({ H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
public static Field<Integer> dayOfYear(Temporal value) {
return extract(value, DatePart.DAY_OF_YEAR);
}
/**
* Get the day of week part of a date.
* <p>
* This is the same as calling {@link #extract(Field, DatePart)}
* with {@link DatePart#DAY_OF_YEAR}
*/
@Support({ H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
public static Field<Integer> dayOfYear(Field<?> field) {
return extract(field, DatePart.DAY_OF_YEAR);
}
/**
* Get the hour part of a date.
* <p>

View File

@ -91,6 +91,8 @@ final class Extract extends AbstractFunction<Integer> {
return dowSun0ToISO(DSL.field("{strftime}('%w', {0})", INTEGER, field));
case DAY_OF_WEEK:
return DSL.field("{strftime}('%w', {0})", INTEGER, field).add(one());
case DAY_OF_YEAR:
return DSL.field("{strftime}('%j', {0})", INTEGER, field);
default:
throw new SQLDialectNotSupportedException("DatePart not supported: " + datePart);
}
@ -145,6 +147,8 @@ final class Extract extends AbstractFunction<Integer> {
throw new SQLDialectNotSupportedException("DatePart not supported: " + datePart);
@ -215,6 +219,10 @@ final class Extract extends AbstractFunction<Integer> {

View File

@ -88,6 +88,7 @@ import static org.jooq.impl.DSL.currentUser;
import static org.jooq.impl.DSL.date;
import static org.jooq.impl.DSL.day;
import static org.jooq.impl.DSL.dayOfWeek;
import static org.jooq.impl.DSL.dayOfYear;
import static org.jooq.impl.DSL.defaultValue;
import static org.jooq.impl.DSL.deg;
import static org.jooq.impl.DSL.denseRank;
@ -4541,6 +4542,8 @@ final class ParserImpl implements Parser {
return field;
else if ((field = parseFieldIsoDayOfWeekIf(ctx)) != null)
return field;
else if ((field = parseFieldDayOfYearIf(ctx)) != null)
return field;
else if (parseFunctionNameIf(ctx, "DEGREES")
|| parseFunctionNameIf(ctx, "DEGREE")
|| parseFunctionNameIf(ctx, "DEG"))
@ -5478,7 +5481,7 @@ final class ParserImpl implements Parser {
private static final Field<?> parseFieldDateAddIf(ParserContext ctx) {
if (parseFunctionNameIf(ctx, "DATEADD")) {
parse(ctx, '(');
DatePart part = parseDatePart2(ctx);
DatePart part = parseDatePart(ctx);
parse(ctx, ',');
Field<Number> interval = (Field<Number>) parseField(ctx, Type.N);
parse(ctx, ',');
@ -5515,31 +5518,24 @@ final class ParserImpl implements Parser {
}
private static final DatePart parseDatePart(ParserContext ctx) {
for (DatePart part : DatePart.values())
if (parseKeywordIf(ctx, part.name()))
return part;
if (parseKeywordIf(ctx, "ISODOW"))
return DatePart.ISO_DAY_OF_WEEK;
throw ctx.exception("Unsupported date part");
}
private static final DatePart parseDatePart2(ParserContext ctx) {
char character = ctx.character();
switch (character) {
case 'd':
case 'D':
if (parseKeywordIf(ctx, "DAYOFYEAR") ||
parseKeywordIf(ctx, "DAY_OF_YEAR") ||
parseKeywordIf(ctx, "DOY") ||
parseKeywordIf(ctx, "DY"))
return DatePart.DAY_OF_YEAR;
else if (parseKeywordIf(ctx, "DAY_OF_WEEK") ||
parseKeywordIf(ctx, "DAYOFWEEK") ||
parseKeywordIf(ctx, "DW"))
return DatePart.DAY_OF_WEEK;
else if (parseKeywordIf(ctx, "DAY") ||
parseKeywordIf(ctx, "DD") ||
parseKeywordIf(ctx, "D"))
return DatePart.DAY;
else if (parseKeywordIf(ctx, "DW"))
return DatePart.DAY_OF_WEEK;
break;
@ -5551,6 +5547,12 @@ final class ParserImpl implements Parser {
break;
case 'i':
case 'I':
if (parseKeywordIf(ctx, "ISODOW") ||
parseKeywordIf(ctx, "ISO_DAY_OF_WEEK"))
return DatePart.ISO_DAY_OF_WEEK;
case 'm':
case 'M':
if (parseKeywordIf(ctx, "MINUTE") ||
@ -6116,6 +6118,18 @@ final class ParserImpl implements Parser {
return null;
}
private static final Field<?> parseFieldDayOfYearIf(ParserContext ctx) {
if (parseFunctionNameIf(ctx, "DAYOFYEAR")
|| parseFunctionNameIf(ctx, "DAY_OF_YEAR")) {
parse(ctx, '(');
Field<Timestamp> f1 = (Field) parseField(ctx, D);
parse(ctx, ')');
return dayOfYear(f1);
}
return null;
}
private static final Field<?> parseFieldHourIf(ParserContext ctx) {
if (parseFunctionNameIf(ctx, "HOUR")) {
parse(ctx, '(');