From b650db1f0d7c603605c76f8427f379db36b2c1a6 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 18 May 2022 11:17:51 +0200 Subject: [PATCH] [jOOQ/jOOQ#5214] Updated MySQL emulation of EXCLUDED for INSERT SELECT --- .../java/org/jooq/impl/InsertQueryImpl.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index b908fca06f..f1a71bba5b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -85,6 +85,7 @@ import static org.jooq.impl.Keywords.K_VALUES; import static org.jooq.impl.Keywords.K_WHERE; import static org.jooq.impl.Names.N_EXCLUDED; import static org.jooq.impl.QueryPartListView.wrap; +import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.aliasedFields; import static org.jooq.impl.Tools.anyMatch; import static org.jooq.impl.Tools.collect; @@ -345,7 +346,7 @@ implements case POSTGRES: case SQLITE: case YUGABYTEDB: { - ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c)); + ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c, false)); ctx.formatSeparator() .start(INSERT_ON_DUPLICATE_KEY_UPDATE) @@ -448,12 +449,12 @@ implements boolean oldQualify = ctx.qualify(); boolean newQualify = ctx.family() != H2 && oldQualify; FieldMapForUpdate um = updateMapComputedOnClientStored(ctx); - - Set> keys = toSQLInsert(ctx); - - // [#5214] TODO: This is incorrect for INSERT .. SELECT boolean requireNewMySQLExcludedEmulation = REQUIRE_NEW_MYSQL_EXCLUDED_EMULATION.contains(ctx.dialect()) && anyMatch(um.values(), v -> v instanceof Excluded); - if (requireNewMySQLExcludedEmulation) + + Set> keys = toSQLInsert(ctx, requireNewMySQLExcludedEmulation); + + // [#5214] The alias only applies with INSERT .. VALUES + if (requireNewMySQLExcludedEmulation && select == null) ctx.formatSeparator() .visit(K_AS).sql(' ').visit(N_EXCLUDED); @@ -520,7 +521,7 @@ implements case POSTGRES: case SQLITE: case YUGABYTEDB: { - ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c)); + ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c, false)); ctx.formatSeparator() .start(INSERT_ON_DUPLICATE_KEY_UPDATE) @@ -569,7 +570,7 @@ implements Field field = table().field(0); update.put(field, field); - toSQLInsert(ctx); + toSQLInsert(ctx, false); ctx.formatSeparator() .start(INSERT_ON_DUPLICATE_KEY_UPDATE) .visit(K_ON_DUPLICATE_KEY_UPDATE) @@ -606,7 +607,7 @@ implements // MySQL has a nice, native syntax for this default: { - toSQLInsert(ctx); + toSQLInsert(ctx, false); ctx.start(INSERT_ON_DUPLICATE_KEY_UPDATE) .end(INSERT_ON_DUPLICATE_KEY_UPDATE); break; @@ -617,7 +618,7 @@ implements // Default mode // ------------ else { - toSQLInsert(ctx); + toSQLInsert(ctx, false); ctx.start(INSERT_ON_DUPLICATE_KEY_UPDATE) .end(INSERT_ON_DUPLICATE_KEY_UPDATE); } @@ -632,7 +633,7 @@ implements return CLAUSES; } - private final Set> toSQLInsert(Context ctx) { + private final Set> toSQLInsert(Context ctx, boolean requireNewMySQLExcludedEmulation) { ctx.start(INSERT_INSERT_INTO) .visit(K_INSERT) .sql(' '); @@ -689,6 +690,8 @@ implements + if (requireNewMySQLExcludedEmulation) + s = selectFrom(s.asTable(DSL.table(N_EXCLUDED), keysFlattened)); // [#8353] TODO: Support overlapping embeddables toSQLInsertSelect(ctx, s);