diff --git a/jOOQ/src/main/java/org/jooq/impl/Expression.java b/jOOQ/src/main/java/org/jooq/impl/Expression.java index 565f96f2ee..f45371051e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Expression.java +++ b/jOOQ/src/main/java/org/jooq/impl/Expression.java @@ -68,6 +68,7 @@ import static org.jooq.impl.ExpressionOperator.SUBTRACT; import java.sql.Timestamp; import java.util.EnumSet; +import java.util.regex.Pattern; import org.jooq.Configuration; import org.jooq.Context; @@ -260,6 +261,12 @@ final class Expression extends AbstractFunction { } } + // E.g. +2 00:00:00.000000000 + private static final Pattern TRUNC_TO_MICROS = Pattern.compile("([^.]*\\.\\d{0,6})\\d{0,3}"); + + /** + * Return the expression to be rendered when the RHS is an interval type + */ private class DateExpression extends AbstractFunction { /** @@ -273,17 +280,12 @@ final class Expression extends AbstractFunction { @Override final Field getFunction0(Configuration configuration) { - if (rhs.get(0).getDataType().isInterval()) { + if (rhs.get(0).getDataType().isInterval()) return getIntervalExpression(configuration); - } - else { + else return getNumberExpression(configuration); - } } - /** - * Return the expression to be rendered when the RHS is an interval type - */ @SuppressWarnings({ "unchecked", "rawtypes" }) private final Field getIntervalExpression(Configuration configuration) { SQLDialect dialect = configuration.dialect(); @@ -295,21 +297,21 @@ final class Expression extends AbstractFunction { case MYSQL: { Interval interval = rhsAsInterval(); - if (operator == SUBTRACT) { + if (operator == SUBTRACT) interval = interval.neg(); - } - if (rhs.get(0).getType() == YearToMonth.class) { + if (rhs.get(0).getType() == YearToMonth.class) return DSL.field("{date_add}({0}, {interval} {1} {year_month})", getDataType(), lhs, Tools.field(interval, String.class)); - } - else { - if (dialect == CUBRID) { - return DSL.field("{date_add}({0}, {interval} {1} {day_millisecond})", getDataType(), lhs, Tools.field(interval, String.class)); - } - else { - return DSL.field("{date_add}({0}, {interval} {1} {day_microsecond})", getDataType(), lhs, Tools.field(interval, String.class)); - } - } + else if (dialect == CUBRID) + return DSL.field("{date_add}({0}, {interval} {1} {day_millisecond})", getDataType(), lhs, Tools.field(interval, String.class)); + + // [#6820] Workaround for bugs: + // https://bugs.mysql.com/bug.php?id=88573 + // https://jira.mariadb.org/browse/MDEV-14452 + else + return DSL.field("{date_add}({0}, {interval} {1} {day_microsecond})", getDataType(), lhs, + Tools.field(TRUNC_TO_MICROS.matcher("" + interval).replaceAll("$1"), String.class) + ); } case DERBY: