From 13fefe6390efafb4f5e32f6c46fc8716adb79a2b Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 13 Nov 2023 11:14:21 +0100 Subject: [PATCH] [jOOQ/jOOQ#15822] Support parsing dynamic intervals in MySQL DATE_ADD() and DATE_SUB() expressions --- .../main/java/org/jooq/impl/ParserImpl.java | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index c9a34cb30f..bdc08759a3 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -8845,7 +8845,9 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { break; case 'I': - if ((field = parseFieldIntervalLiteralIf()) != null) + + // [#8792] TODO: Support parsing interval expressions + if ((field = parseFieldIntervalLiteralIf(true)) != null) return field; else if (parseFunctionNameIf("ISO_DAY_OF_WEEK")) return isoDayOfWeek(parseFieldParenthesised()); @@ -10572,7 +10574,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { return time; } - private final Field parseFieldIntervalLiteralIf() { + private final Field parseFieldIntervalLiteralIf(boolean parseUnknownSyntaxAsIdentifier) { int p = position(); if (parseKeywordIf("INTERVAL")) { @@ -10615,7 +10617,9 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { else { position(p); - return field(parseIdentifier()); + + if (parseUnknownSyntaxAsIdentifier) + return field(parseIdentifier()); } } } @@ -10623,6 +10627,16 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { return null; } + private final Field parseFieldMySQLIntervalLiteralIf(BiFunction, ? super DatePart, ? extends Field> f) { + if (parseKeywordIf("INTERVAL")) { + Field interval = parseField(); + DatePart part = parseIntervalDatePart(); + return f.apply(interval, part); + } + + return null; + } + private final Interval parsePostgresIntervalLiteralIf() { int p = position(); @@ -10895,6 +10909,8 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { // MySQL style else if (parseFunctionNameIf("DATE_ADD") || (sub = parseFunctionNameIf("DATE_SUB"))) { + boolean s = sub; + parse('('); Field d = parseField(); @@ -10903,10 +10919,20 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { parse(','); // [#8792] TODO: Support parsing interval expressions - Field interval = parseFieldIntervalLiteralIf(); - parse(')'); + Field interval = parseFieldIntervalLiteralIf(false); - return sub ? DSL.dateSub((Field) date, (Field) interval) : DSL.dateAdd((Field) date, (Field) interval); + if (interval == null) { + interval = parseFieldMySQLIntervalLiteralIf((i, p) -> s ? DSL.dateSub((Field) date, (Field) i, p) : DSL.dateAdd((Field) date, (Field) i, p)); + + if (interval != null) { + parse(')'); + return interval; + } + } + else { + parse(')'); + return s ? DSL.dateSub((Field) date, (Field) interval) : DSL.dateAdd((Field) date, (Field) interval); + } } return null;