From 9971ff8e96a0dfd51452f0108b3c9c29e0f6f46e Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 8 Nov 2021 11:02:50 +0100 Subject: [PATCH] [jOOQ/jOOQ#9864] Support INSERT .. DEFAULT VALUES If users specify VALUES(), but the list is effectively empty, because all supplied fields are readonly and we use the default IGNORE behaviour, then users have effectively specified DEFAULT VALUES --- .../java/org/jooq/impl/DeleteQueryImpl.java | 1 + .../java/org/jooq/impl/FieldMapForUpdate.java | 5 +++++ .../org/jooq/impl/FieldMapsForInsert.java | 22 ++++++++++++++++++- .../java/org/jooq/impl/InsertQueryImpl.java | 14 ++++++++++-- .../main/java/org/jooq/impl/MergeImpl.java | 5 +++++ .../java/org/jooq/impl/TableRecordImpl.java | 2 +- .../org/jooq/impl/UpdatableRecordImpl.java | 2 +- .../java/org/jooq/impl/UpdateQueryImpl.java | 6 +++++ 8 files changed, 52 insertions(+), 5 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java index 83565481a2..1fafcd8fb9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java @@ -103,6 +103,7 @@ import org.jooq.Param; // ... import org.jooq.Record; import org.jooq.SQLDialect; +import org.jooq.Scope; import org.jooq.Table; import org.jooq.TableLike; import org.jooq.conf.ParamType; diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java index fcbd2b2bea..43c615e1cc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapForUpdate.java @@ -172,4 +172,9 @@ final class FieldMapForUpdate extends AbstractQueryPartMap, Field> i + + + + + } diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java index 57d6f0de19..3f9cd1bd89 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java @@ -46,10 +46,12 @@ import static org.jooq.Clause.INSERT_VALUES; import static org.jooq.SQLDialect.POSTGRES; // ... import static org.jooq.SQLDialect.YUGABYTE; +import static org.jooq.conf.WriteIfReadonly.IGNORE; import static org.jooq.conf.WriteIfReadonly.THROW; import static org.jooq.impl.DSL.name; import static org.jooq.impl.Keywords.K_DEFAULT_VALUES; import static org.jooq.impl.Keywords.K_VALUES; +import static org.jooq.impl.QueryPartCollectionView.wrap; import static org.jooq.impl.Tools.anyMatch; import static org.jooq.impl.Tools.collect; import static org.jooq.impl.Tools.filter; @@ -72,6 +74,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.function.Function; +import org.jooq.Configuration; import org.jooq.Context; import org.jooq.DataType; import org.jooq.Field; @@ -225,6 +228,20 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple + + + + + + + + + + + + + + @@ -525,7 +542,10 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple // [#989] Avoid qualifying fields in INSERT field declaration List> fields = collect(removeReadonly(ctx, flattenCollection(values.keySet(), true, true), e -> e)); - ctx.sql(" (").visit(new QueryPartCollectionView<>(fields).qualify(false)).sql(')'); + + if (!fields.isEmpty()) + ctx.sql(" (").visit(wrap(fields).qualify(false)).sql(')'); + return fields; } diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index eab926824c..6ae4c63dfa 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -119,6 +119,7 @@ import org.jooq.Operator; import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.SQLDialect; +import org.jooq.Scope; import org.jooq.Select; import org.jooq.Table; import org.jooq.TableField; @@ -286,6 +287,15 @@ final class InsertQueryImpl extends AbstractStoreQuery impl defaultValues = true; } + private final boolean defaultValues(Configuration c) { + + + + + + return defaultValues; + } + @Override public final void setSelect(Field[] f, Select s) { setSelect(Arrays.asList(f), s); @@ -685,7 +695,7 @@ final class InsertQueryImpl extends AbstractStoreQuery impl ctx.data().remove(DATA_INSERT_SELECT_WITHOUT_INSERT_COLUMN_LIST); ctx.data().remove(DATA_INSERT_SELECT); } - else if (defaultValues) { + else if (defaultValues(ctx.configuration())) { switch (ctx.family()) { @@ -963,7 +973,7 @@ final class InsertQueryImpl extends AbstractStoreQuery impl @Override public final boolean isExecutable() { - return insertMaps.isExecutable() || defaultValues || select != null; + return insertMaps.isExecutable() || defaultValues(configuration()) || select != null; } diff --git a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java index 88aeb06d67..157cdb4be2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java @@ -1478,6 +1478,11 @@ implements + + + + + diff --git a/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java index be7c8076ff..5e30157a25 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java @@ -166,7 +166,7 @@ public class TableRecordImpl> extends AbstractQualified InsertQuery insert = create.insertQuery(getTable()); List> changedFields = addChangedValues(storeFields, insert, false); - if (!insert.isExecutable()) { + if (changedFields.isEmpty()) { // Don't store records if no value was set by client code if (FALSE.equals(create.settings().isInsertUnchangedRecords())) { diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java index 4a5424dcaf..0d9d0fd833 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java @@ -280,7 +280,7 @@ public class UpdatableRecordImpl> extends TableReco List> changedFields = addChangedValues(storeFields, query, merge); Tools.addConditions(query, this, keys); - if (!query.isExecutable()) { + if (changedFields.isEmpty()) { switch (StringUtils.defaultIfNull(create().settings().getUpdateUnchangedRecords(), UpdateUnchangedRecords.NEVER)) { // Don't store records if no value was set by client code diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java index 15278c2174..22688c3fa7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java @@ -158,6 +158,7 @@ import org.jooq.Row8; import org.jooq.Row9; import org.jooq.RowN; import org.jooq.SQLDialect; +import org.jooq.Scope; import org.jooq.Select; import org.jooq.Table; import org.jooq.TableLike; @@ -750,6 +751,11 @@ final class UpdateQueryImpl extends AbstractStoreQuery impl + + + + + private final void acceptFrom(Context ctx) { ctx.start(UPDATE_FROM);