From 358c4ec426d587eb40f3c0fb9fc2c35c0be12f11 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 6 May 2020 12:58:21 +0200 Subject: [PATCH] [jOOQ/jOOQ#10165] Add support for MySQL's INSERT() function --- jOOQ/src/main/java/org/jooq/impl/DSL.java | 16 +++++++++++ jOOQ/src/main/java/org/jooq/impl/Names.java | 1 + jOOQ/src/main/java/org/jooq/impl/Overlay.java | 12 +++++++-- .../main/java/org/jooq/impl/ParserImpl.java | 27 ++++++++++++++++--- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 8e4bc7f81d..1ad4fd520d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -14306,6 +14306,22 @@ public class DSL { return new Overlay(nullSafe(in), nullSafe(placing), nullSafe(startIndex), nullSafe(length)); } + /** + * Get the insert(in, startIndex, length, placing) function. + */ + @Support + public static Field insert(Field in, Number startIndex, Number length, String placing) { + return insert(nullSafe(in), Tools.field(startIndex), Tools.field(length), Tools.field(placing)); + } + + /** + * Get the insert(in, startIndex, length, placing) function. + */ + @Support + public static Field insert(Field in, Field startIndex, Field length, Field placing) { + return overlay(in, placing, startIndex, length); + } + /** * Get the ascii(field) function. * diff --git a/jOOQ/src/main/java/org/jooq/impl/Names.java b/jOOQ/src/main/java/org/jooq/impl/Names.java index 6d03a3286d..7329cc8241 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Names.java +++ b/jOOQ/src/main/java/org/jooq/impl/Names.java @@ -113,6 +113,7 @@ final class Names { static final Name N_IF = unquotedName("if"); static final Name N_IFNULL = unquotedName("ifnull"); static final Name N_IIF = unquotedName("iif"); + static final Name N_INSERT = unquotedName("insert"); static final Name N_INSTR = unquotedName("instr"); static final Name N_JOIN = unquotedName("join"); static final Name N_JSON_AGG = unquotedName("json_agg"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Overlay.java b/jOOQ/src/main/java/org/jooq/impl/Overlay.java index c78f777e62..b7f1ea1f90 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Overlay.java +++ b/jOOQ/src/main/java/org/jooq/impl/Overlay.java @@ -62,6 +62,7 @@ import static org.jooq.impl.DSL.inline; import static org.jooq.impl.Keywords.K_FOR; import static org.jooq.impl.Keywords.K_FROM; import static org.jooq.impl.Keywords.K_PLACING; +import static org.jooq.impl.Names.N_INSERT; import static org.jooq.impl.Names.N_OVERLAY; import java.util.Set; @@ -77,6 +78,7 @@ final class Overlay extends AbstractField { private static final long serialVersionUID = 3544690069533526544L; private static final Set NO_SUPPORT = SQLDialect.supportedBy(DERBY, H2, HSQLDB, MARIADB, MYSQL, SQLITE); + private static final Set SUPPORT_INSERT = SQLDialect.supportedBy(MARIADB, MYSQL); private final Field in; private final Field placing; @@ -107,7 +109,10 @@ final class Overlay extends AbstractField { if (l != null) { - if (NO_SUPPORT.contains(ctx.family())) { + if (SUPPORT_INSERT.contains(ctx.dialect())) { + ctx.visit(N_INSERT).sql('(').visit(in).sql(", ").visit(startIndex).sql(", ").visit(l).sql(", ").visit(placing).sql(')'); + } + else if (NO_SUPPORT.contains(ctx.dialect())) { ctx.visit( DSL.substring(in, inline(1), startIndex.minus(inline(1))) .concat(placing) @@ -122,7 +127,10 @@ final class Overlay extends AbstractField { } } else { - if (NO_SUPPORT.contains(ctx.family())) { + if (SUPPORT_INSERT.contains(ctx.dialect())) { + ctx.visit(N_INSERT).sql('(').visit(in).sql(", ").visit(startIndex).sql(", ").visit(DSL.length(placing)).sql(", ").visit(placing).sql(')'); + } + else if (NO_SUPPORT.contains(ctx.dialect())) { ctx.visit( DSL.substring(in, inline(1), startIndex.minus(inline(1))) .concat(placing) diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index b0ddb2c643..32216cd133 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -151,6 +151,7 @@ import static org.jooq.impl.DSL.hour; import static org.jooq.impl.DSL.ifnull; import static org.jooq.impl.DSL.iif; import static org.jooq.impl.DSL.inline; +import static org.jooq.impl.DSL.insert; import static org.jooq.impl.DSL.isnull; import static org.jooq.impl.DSL.isoDayOfWeek; import static org.jooq.impl.DSL.jsonEntry; @@ -5669,10 +5670,8 @@ final class ParserImpl implements Parser { List result = new ArrayList<>(); do { - if (peekKeyword(ctx, KEYWORDS_IN_SELECT)) - throw ctx.exception("Select keywords must be quoted"); - QualifiedAsterisk qa; + if (parseIf(ctx, '*')) { if (parseKeywordIf(ctx, "EXCEPT")) { parse(ctx, '('); @@ -6360,6 +6359,10 @@ final class ParserImpl implements Parser { if ((field = parseFieldInstrIf(ctx)) != null) return field; + if (S.is(type)) + if ((field = parseFieldInsertIf(ctx)) != null) + return field; + if ((field = parseFieldIfnullIf(ctx)) != null) return field; else if ((field = parseFieldIsnullIf(ctx)) != null) @@ -8274,6 +8277,24 @@ final class ParserImpl implements Parser { return null; } + private static final Field parseFieldInsertIf(ParserContext ctx) { + if (parseFunctionNameIf(ctx, "INSERT")) { + parse(ctx, '('); + Field f1 = (Field) parseField(ctx, S); + parse(ctx, ','); + Field f2 = (Field) parseField(ctx, N); + parse(ctx, ','); + Field f3 = (Field) parseField(ctx, N); + parse(ctx, ','); + Field f4 = (Field) parseField(ctx, S); + parse(ctx, ')'); + + return insert(f1, f2, f3, f4); + } + + return null; + } + private static final Field parseFieldOverlayIf(ParserContext ctx) { if (parseFunctionNameIf(ctx, "OVERLAY")) { parse(ctx, '(');