From 37727bee41ec14817dfa62eae75bb59cb21a2930 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Wed, 5 Jun 2019 08:44:08 +0200 Subject: [PATCH] [jOOQ/jOOQ#8735] Support Offset[Date]Time and Instant for SQLite For SQLite the Java 8 time types Offset[Date|DateTime|Time] and Instant are now supported. SQLite basically supports date and time data with time zones as input. Returned values are however always in Zulu / UTC time, as with some other dialects. --- jOOQ/src/main/java/org/jooq/impl/DSL.java | 18 +++---- .../main/java/org/jooq/impl/DateOrTime.java | 16 +++--- .../java/org/jooq/impl/DefaultBinding.java | 54 +++++++++++++------ 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 34183ce74e..7deccd1068 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -15769,7 +15769,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetTime(String value) { return Tools.field(Convert.convert(value, OffsetTime.class)); } @@ -15783,7 +15783,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetTime(OffsetTime value) { return Tools.field(value); } @@ -15797,7 +15797,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetTime(Field field) { return new DateOrTime(field, SQLDataType.OFFSETTIME); } @@ -15811,7 +15811,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetDateTime(String value) { return Tools.field(Convert.convert(value, OffsetDateTime.class)); } @@ -15825,7 +15825,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetDateTime(OffsetDateTime value) { return Tools.field(value); } @@ -15839,7 +15839,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field offsetDateTime(Field field) { return new DateOrTime(field, SQLDataType.OFFSETDATETIME); } @@ -15853,7 +15853,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field instant(String value) { return Tools.field(Convert.convert(value, Instant.class)); } @@ -15867,7 +15867,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field instant(Instant value) { return Tools.field(value); } @@ -15881,7 +15881,7 @@ public class DSL { * UTC. Regardless of this fact, the result should be the same * {@link Instant} (in UTC) as the input. */ - @Support({ H2, HSQLDB, POSTGRES }) + @Support({ H2, HSQLDB, POSTGRES, SQLITE }) public static Field instant(Field field) { return new DateOrTime(field, SQLDataType.INSTANT); } diff --git a/jOOQ/src/main/java/org/jooq/impl/DateOrTime.java b/jOOQ/src/main/java/org/jooq/impl/DateOrTime.java index f4869c403a..31d2ab034b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DateOrTime.java +++ b/jOOQ/src/main/java/org/jooq/impl/DateOrTime.java @@ -37,7 +37,6 @@ */ package org.jooq.impl; -import static org.jooq.impl.DSL.keyword; import static org.jooq.impl.Tools.castIfNeeded; import org.jooq.Configuration; @@ -84,14 +83,13 @@ final class DateOrTime extends AbstractFunction { return DSL.field("{" + name(getDataType()) + "}({0})", getDataType(), field); case SQLITE: { - String name = - getDataType().isDate() - ? "date" - : getDataType().isTime() - ? "time" - : "datetime"; - - return DSL.field("{0}({1})", getDataType(), keyword(name), field); + if (getDataType().isDate()) + return DSL.field("{date}({0})", getDataType(), field); + else if (getDataType().isTime()) + // [#8733] No fractional seconds for time literals + return DSL.field("{time}({0})", getDataType(), field); + else + return DSL.field("{strftime}('%Y-%m-%d %H:%M:%f', {0})", getDataType(), field); } default: diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 7b537ba83d..6cf68fa548 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -2656,14 +2656,22 @@ public class DefaultBinding implements Binding { final void sqlInline0(BindingSQLContext ctx, OffsetDateTime value) { SQLDialect family = ctx.family(); - // [#5806] H2 doesn't support TIMESTAMP WITH TIME ZONE literals, see - if (family == H2) - ctx.render().visit(K_CAST).sql("('").sql(escape(format(value, family), ctx.render())).sql("' ") - .visit(K_AS).sql(' ').visit(K_TIMESTAMP_WITH_TIME_ZONE).sql(')'); + switch (family) { + // [#5806] H2 doesn't support TIMESTAMP WITH TIME ZONE literals, see + case H2: + ctx.render().visit(K_CAST).sql("('").sql(escape(format(value, family), ctx.render())).sql("' ") + .visit(K_AS).sql(' ').visit(K_TIMESTAMP_WITH_TIME_ZONE).sql(')'); + break; - // [#5895] HSQLDB derives the specific data type from the literal - else if (family == HSQLDB) - ctx.render().visit(K_TIMESTAMP).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\''); + // [#5895] HSQLDB derives the specific data type from the literal + case HSQLDB: + ctx.render().visit(K_TIMESTAMP).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\''); + break; + + // [#8735] SQLite renders as ISO formatted string literals + case SQLITE: + ctx.render().sql('\'').sql(escape(format(value, family), ctx.render())).sql('\''); + break; @@ -2675,9 +2683,14 @@ public class DefaultBinding implements Binding { - // Some dialects implement SQL standard time literals - else - ctx.render().visit(K_TIMESTAMP_WITH_TIME_ZONE).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\''); + + + + // Some dialects implement SQL standard time literals + default: + ctx.render().visit(K_TIMESTAMP_WITH_TIME_ZONE).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\''); + break; + } } @Override @@ -2826,9 +2839,16 @@ public class DefaultBinding implements Binding { @Override final void sqlInline0(BindingSQLContext ctx, OffsetTime value) { - // [#5895] HSQLDB derives the specific data type from the literal - if (ctx.family() == HSQLDB) - ctx.render().visit(K_TIME).sql(" '").sql(escape(format(value), ctx.render())).sql('\''); + switch (ctx.family()) { + // [#5895] HSQLDB derives the specific data type from the literal + case HSQLDB: + ctx.render().visit(K_TIME).sql(" '").sql(escape(format(value), ctx.render())).sql('\''); + break; + + // [#8735] SQLite renders as ISO formatted string literals + case SQLITE: + ctx.render().sql('\'').sql(escape(format(value), ctx.render())).sql('\''); + break; @@ -2836,9 +2856,11 @@ public class DefaultBinding implements Binding { - // Some dialects implement SQL standard time literals - else - ctx.render().visit(K_TIME_WITH_TIME_ZONE).sql(" '").sql(escape(format(value), ctx.render())).sql('\''); + // Some dialects implement SQL standard time literals + default: + ctx.render().visit(K_TIME_WITH_TIME_ZONE).sql(" '").sql(escape(format(value), ctx.render())).sql('\''); + break; + } } @Override