[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
This commit is contained in:
Lukas Eder 2021-11-08 11:02:50 +01:00
parent cd615bcf51
commit 9971ff8e96
8 changed files with 52 additions and 5 deletions

View File

@ -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;

View File

@ -172,4 +172,9 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> i
}

View File

@ -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<Field<?>> 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;
}

View File

@ -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<R extends Record> extends AbstractStoreQuery<R> 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<R extends Record> extends AbstractStoreQuery<R> 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<R extends Record> extends AbstractStoreQuery<R> impl
@Override
public final boolean isExecutable() {
return insertMaps.isExecutable() || defaultValues || select != null;
return insertMaps.isExecutable() || defaultValues(configuration()) || select != null;
}

View File

@ -1478,6 +1478,11 @@ implements

View File

@ -166,7 +166,7 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractQualified
InsertQuery<R> insert = create.insertQuery(getTable());
List<Field<?>> 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())) {

View File

@ -280,7 +280,7 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
List<Field<?>> 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

View File

@ -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<R extends Record> extends AbstractStoreQuery<R> impl
private final void acceptFrom(Context<?> ctx) {
ctx.start(UPDATE_FROM);