diff --git a/jOOQ/src/main/java/org/jooq/impl/TruncDate.java b/jOOQ/src/main/java/org/jooq/impl/TruncDate.java index 05b6fbd547..0f319f9dae 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TruncDate.java +++ b/jOOQ/src/main/java/org/jooq/impl/TruncDate.java @@ -37,6 +37,7 @@ */ package org.jooq.impl; +import static org.jooq.DatePart.YEAR; import static org.jooq.impl.DSL.function; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.keyword; @@ -44,6 +45,7 @@ import static org.jooq.impl.Keywords.K_CAST; import static org.jooq.impl.Names.N_DATETIME_TRUNC; import static org.jooq.impl.Names.N_DATE_TRUNC; import static org.jooq.impl.Names.N_TRUNC; +import static org.jooq.impl.SQLDataType.VARCHAR; import static org.jooq.impl.Tools.castIfNeeded; import java.sql.Date; @@ -73,6 +75,7 @@ final class TruncDate extends AbstractField implements UNotYetImplemented String keyword = null; String format = null; + familySwitch: switch (ctx.family()) { // [http://jira.cubrid.org/browse/ENGINE-120] This currently doesn't work for all date parts in CUBRID @@ -85,7 +88,7 @@ final class TruncDate extends AbstractField implements UNotYetImplemented case HOUR: keyword = "HH"; break; case MINUTE: keyword = "MI"; break; case SECOND: keyword = "SS"; break; - default: throwUnsupported(); + default: acceptDefaultEmulation(ctx); break familySwitch; } ctx.visit(N_TRUNC).sql('(').visit(date).sql(", ").visit(inline(keyword)).sql(')'); @@ -100,7 +103,7 @@ final class TruncDate extends AbstractField implements UNotYetImplemented case HOUR: format = "yyyy-MM-dd HH"; break; case MINUTE: format = "yyyy-MM-dd HH:mm"; break; case SECOND: format = "yyyy-MM-dd HH:mm:ss"; break; - default: throwUnsupported(); + default: acceptDefaultEmulation(ctx); break familySwitch; } ctx.visit(DSL.keyword("parsedatetime")).sql('(') @@ -129,17 +132,7 @@ final class TruncDate extends AbstractField implements UNotYetImplemented case POSTGRES: case YUGABYTEDB: { - switch (part) { - case YEAR: keyword = "year"; break; - case MONTH: keyword = "month"; break; - case DAY: keyword = "day"; break; - case HOUR: keyword = "hour"; break; - case MINUTE: keyword = "minute"; break; - case SECOND: keyword = "second"; break; - default: throwUnsupported(); - } - - ctx.visit(N_DATE_TRUNC).sql('(').visit(inline(keyword)).sql(", ").visit(date).sql(')'); + ctx.visit(N_DATE_TRUNC).sql('(').visit(inline(part.toKeyword().toString())).sql(", ").visit(date).sql(')'); break; } @@ -256,6 +249,45 @@ final class TruncDate extends AbstractField implements UNotYetImplemented } } + private final void acceptDefaultEmulation(Context ctx) { + switch (part) { + case DECADE: + ctx.visit(padYear(ctx, 3, DSL.extract(date, part)).concat(dateOrTimestampLiteral("0-01-01")).cast(getDataType())); + break; + + case CENTURY: + ctx.visit(padYear(ctx, 2, DSL.extract(date, part).minus(inline(1))).concat(dateOrTimestampLiteral("01-01-01")).cast(getDataType())); + break; + + case MILLENNIUM: + ctx.visit(DSL.extract(date, part).minus(inline(1)).cast(VARCHAR(10)).concat(dateOrTimestampLiteral("001-01-01")).cast(getDataType())); + break; + + case QUARTER: + ctx.visit(padYear(ctx, 4, DSL.extract(date, YEAR)).concat(inline("-")).concat(DSL.extract(date, part).minus(inline(1)).times(inline(3)).plus(inline(1)).cast(VARCHAR(10))).concat(dateOrTimestampLiteral("-01")).cast(getDataType())); + break; + + default: + throwUnsupported(); + break; + } + } + + private final Field padYear(Context ctx, int length, Field year) { + switch (ctx.family()) { + + case HSQLDB: + return DSL.lpad(year.cast(VARCHAR(10)), inline(length), inline("0")); + + default: + return year.cast(VARCHAR(10)); + } + } + + private final Field dateOrTimestampLiteral(String string) { + return DSL.inline(getDataType().isDate() ? string : string + " 00:00:00"); + } + private final void throwUnsupported() { throw new UnsupportedOperationException("Unknown date part : " + part); }