From f0ac0ea00cc77e4f2be74215a5bdd17b4bef443f Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 22 Aug 2018 13:39:01 +0200 Subject: [PATCH] [#7793] Support DatePart.DAY_OF_YEAR --- .../resources/org/jooq/web/grammar-3.12.txt | 16 ++++++- jOOQ/src/main/java/org/jooq/impl/DSL.java | 37 ++++++++++++++++ jOOQ/src/main/java/org/jooq/impl/Extract.java | 8 ++++ .../main/java/org/jooq/impl/ParserImpl.java | 42 ++++++++++++------- 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt index 8565f20dc4..8afc2935b5 100644 --- a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt +++ b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt @@ -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 ')' diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index e4496c20de..d7f68fe00c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -14888,6 +14888,43 @@ public class DSL { return extract(field, DatePart.ISO_DAY_OF_WEEK); } + /** + * Get the day of week part of a date. + *

+ * 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 dayOfYear(java.util.Date value) { + return extract(value, DatePart.DAY_OF_YEAR); + } + + + + /** + * Get the day of week part of a date. + *

+ * 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 dayOfYear(Temporal value) { + return extract(value, DatePart.DAY_OF_YEAR); + } + + + + /** + * Get the day of week part of a date. + *

+ * 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 dayOfYear(Field field) { + return extract(field, DatePart.DAY_OF_YEAR); + } + /** * Get the hour part of a date. *

diff --git a/jOOQ/src/main/java/org/jooq/impl/Extract.java b/jOOQ/src/main/java/org/jooq/impl/Extract.java index b5ef7e7972..7e21479000 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Extract.java +++ b/jOOQ/src/main/java/org/jooq/impl/Extract.java @@ -91,6 +91,8 @@ final class Extract extends AbstractFunction { 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 { + + throw new SQLDialectNotSupportedException("DatePart not supported: " + datePart); @@ -215,6 +219,10 @@ final class Extract extends AbstractFunction { + + + + diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index b45f93f89c..6e713a0a8a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -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 interval = (Field) 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 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, '(');