From be023ec8bfcd1e1a481be5cbbf87a5151133342a Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 21 Apr 2022 14:48:41 +0200 Subject: [PATCH] [jOOQ/jOOQ#13468] Work around SQLite INSERT .. SELECT .. ON CONFLICT bug --- .../java/org/jooq/impl/FieldMapForUpdate.java | 1 + .../java/org/jooq/impl/FieldMapsForInsert.java | 1 + .../java/org/jooq/impl/InsertQueryImpl.java | 18 ++++++++++-------- .../java/org/jooq/impl/SelectQueryImpl.java | 2 +- jOOQ/src/main/java/org/jooq/impl/Tools.java | 10 ++++++++-- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java index b4695f0100..d5a5a35999 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java @@ -417,6 +417,7 @@ final class FieldMapForUpdate extends AbstractQueryPartMap insertSelect(Context ctx, GeneratorStatementType statementType) { diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index 797202918a..8a77b70ce6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -58,6 +58,7 @@ import static org.jooq.SQLDialect.MYSQL; // ... import static org.jooq.SQLDialect.SQLITE; // ... +// ... import static org.jooq.impl.DSL.constraint; import static org.jooq.impl.DSL.falseCondition; import static org.jooq.impl.DSL.name; @@ -67,7 +68,6 @@ import static org.jooq.impl.DSL.select; import static org.jooq.impl.DSL.selectFrom; import static org.jooq.impl.DSL.selectOne; import static org.jooq.impl.FieldMapsForInsert.toSQLInsertSelect; -import static org.jooq.impl.FieldsImpl.fieldsRow0; import static org.jooq.impl.Keywords.K_DEFAULT; import static org.jooq.impl.Keywords.K_DEFAULT_VALUES; import static org.jooq.impl.Keywords.K_DO_NOTHING; @@ -92,13 +92,13 @@ import static org.jooq.impl.Tools.unqualified; import static org.jooq.impl.Tools.BooleanDataKey.DATA_CONSTRAINT_REFERENCE; import static org.jooq.impl.Tools.BooleanDataKey.DATA_INSERT_SELECT; import static org.jooq.impl.Tools.BooleanDataKey.DATA_INSERT_SELECT_WITHOUT_INSERT_COLUMN_LIST; +import static org.jooq.impl.Tools.BooleanDataKey.DATA_MANDATORY_WHERE_CLAUSE; import static org.jooq.impl.Tools.DataKey.DATA_ON_DUPLICATE_KEY_WHERE; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -338,7 +338,8 @@ implements case POSTGRES: case SQLITE: case YUGABYTEDB: { - toSQLInsert(ctx); + ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c)); + ctx.formatSeparator() .start(INSERT_ON_DUPLICATE_KEY_UPDATE) .visit(K_ON_CONFLICT) @@ -494,7 +495,8 @@ implements case POSTGRES: case SQLITE: case YUGABYTEDB: { - toSQLInsert(ctx); + ctx.data(DATA_MANDATORY_WHERE_CLAUSE, ctx.family() == SQLITE, c -> toSQLInsert(c)); + ctx.formatSeparator() .start(INSERT_ON_DUPLICATE_KEY_UPDATE) .visit(K_ON_CONFLICT); @@ -848,11 +850,11 @@ implements - // [#6375] INSERT .. VALUES and INSERT .. SELECT distinction also in MERGE - t = s.asTable("t", map(f, Field::getName, String[]::new)); - + // [#6375] INSERT .. VALUES and INSERT .. SELECT distinction also in MERGE if (NO_SUPPORT_DERIVED_COLUMN_LIST_IN_MERGE_USING.contains(ctx.dialect())) - t = selectFrom(t).asTable("t"); + t = new AliasedSelect((Select) s, true, true, map(f, Field::getUnqualifiedName, Name[]::new)).as("t"); + else + t = s.asTable("t", map(f, Field::getName, String[]::new)); } MergeOnConditionStep on = t != null diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index b1011f2c26..07bdb169c1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -2341,7 +2341,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp .visit(K_WHERE) .sql(' ') .visit(falseCondition()); - else if (!where.hasWhere() && semiAntiJoinPredicates == null) + else if (!where.hasWhere() && semiAntiJoinPredicates == null && !TRUE.equals(context.data().get(BooleanDataKey.DATA_MANDATORY_WHERE_CLAUSE))) ; else { ConditionProviderImpl actual = new ConditionProviderImpl(); diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index f836fdc8af..0fb56b25c6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -401,8 +401,14 @@ final class Tools { enum BooleanDataKey { /** - * [#1520] Count the number of bind values, and potentially enforce a static - * statement. + * [#13468] The WHERE clause in a SELECT is mandatory for the current + * scope. + */ + DATA_MANDATORY_WHERE_CLAUSE, + + /** + * [#1520] Count the number of bind values, and potentially enforce a + * static statement. */ DATA_COUNT_BIND_VALUES,