[jOOQ/jOOQ#7539] Emulate DEFAULT in UPDATE

This commit is contained in:
Lukas Eder 2024-10-17 11:07:39 +02:00
parent e97216bb10
commit c5d1e154ae
4 changed files with 50 additions and 22 deletions

View File

@ -37,17 +37,35 @@
*/
package org.jooq.impl;
// ...
import static org.jooq.SQLDialect.CLICKHOUSE;
// ...
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
import static org.jooq.impl.Keywords.K_DEFAULT;
import static org.jooq.impl.Names.N_DEFAULT;
import static org.jooq.impl.Tools.orElse;
import java.util.Set;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.SQLDialect;
/**
* @author Lukas Eder
*/
final class Default<T> extends AbstractField<T> implements QOM.Default<T> {
static final Set<SQLDialect> NO_SUPPORT_DEFAULT_EXPRESSION_INSERT = SQLDialect.supportedBy(SQLITE);
static final Set<SQLDialect> NO_SUPPORT_DEFAULT_EXPRESSION_UPDATE = SQLDialect.supportedBy(CLICKHOUSE, SQLITE);
Default(DataType<T> type) {
super(N_DEFAULT, type);
}
@ -56,4 +74,25 @@ final class Default<T> extends AbstractField<T> implements QOM.Default<T> {
public final void accept(Context<?> ctx) {
ctx.visit(K_DEFAULT);
}
static final Field<?> patchDefaultForInsert(Context<?> ctx, Field<?> d, Field<?> f) {
if (NO_SUPPORT_DEFAULT_EXPRESSION_INSERT.contains(ctx.dialect()))
return patchDefault(d, f);
return d;
}
static final Field<?> patchDefaultForUpdate(Context<?> ctx, Field<?> d, Field<?> f) {
if (NO_SUPPORT_DEFAULT_EXPRESSION_UPDATE.contains(ctx.dialect()))
return patchDefault(d, f);
return d;
}
static final Field<?> patchDefault(Field<?> d, Field<?> f) {
if (d instanceof Default)
return orElse(f.getDataType().default_(), () -> DSL.inline(null, f));
return d;
}
}

View File

@ -77,7 +77,7 @@ import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.when;
import static org.jooq.impl.FieldMapsForInsert.patchDefault;
import static org.jooq.impl.Default.patchDefaultForUpdate;
import static org.jooq.impl.Keywords.K_ROW;
import static org.jooq.impl.Tools.anyMatch;
import static org.jooq.impl.Tools.apply;
@ -237,7 +237,7 @@ extends
Field<?> k = multiRow.field(i);
Field<?> v = multiValue.field(i);
map.put(k, patchDefault(ctx, Tools.field(v, k), k));
map.put(k, patchDefaultForUpdate(ctx, Tools.field(v, k), k));
}
ctx.visit(map);
@ -344,7 +344,7 @@ extends
else
ctx.visit(patchDefault(ctx, (Field) value, (Field) key));
ctx.visit(patchDefaultForUpdate(ctx, (Field) value, (Field) key));
}
if (assignmentClause != null)

View File

@ -45,6 +45,7 @@ import static org.jooq.Clause.INSERT_SELECT;
import static org.jooq.Clause.INSERT_VALUES;
// ...
// ...
import static org.jooq.SQLDialect.CLICKHOUSE;
// ...
// ...
// ...
@ -62,6 +63,8 @@ import static org.jooq.conf.WriteIfReadonly.THROW;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.selectFrom;
import static org.jooq.impl.Default.patchDefault;
import static org.jooq.impl.Default.patchDefaultForInsert;
import static org.jooq.impl.Keywords.K_DEFAULT_VALUES;
import static org.jooq.impl.Keywords.K_VALUES;
import static org.jooq.impl.Names.N_T;
@ -120,9 +123,8 @@ import org.jooq.impl.Tools.ExtendedDataKey;
* @author Lukas Eder
*/
final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImplemented {
static final Set<SQLDialect> CASTS_NEEDED = SQLDialect.supportedBy(POSTGRES, TRINO, YUGABYTEDB);
static final Set<SQLDialect> CASTS_NEEDED_FOR_MERGE = SQLDialect.supportedBy(POSTGRES, YUGABYTEDB);
static final Set<SQLDialect> NO_SUPPORT_DEFAULT_EXPRESSION = SQLDialect.supportedBy(SQLITE);
static final Set<SQLDialect> CASTS_NEEDED = SQLDialect.supportedBy(POSTGRES, TRINO, YUGABYTEDB);
static final Set<SQLDialect> CASTS_NEEDED_FOR_MERGE = SQLDialect.supportedBy(POSTGRES, YUGABYTEDB);
final Table<?> table;
final Map<Field<?>, Field<?>> empty;
@ -445,7 +447,7 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple
for (int i = 0; i < rows; i++) {
int row = i;
Select<Record> iteration = DSL.select(Tools.map(
v.entrySet(), e -> patchDefault0(castNullsIfNeeded(ctx, needsCast, e.getValue().get(row)), e.getKey())
v.entrySet(), e -> patchDefault(castNullsIfNeeded(ctx, needsCast, e.getValue().get(row)), e.getKey())
));
if (select == null)
@ -515,7 +517,7 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple
ctx.visit(patchDefault(ctx, list.get(row), e.getKey()));
ctx.visit(patchDefaultForInsert(ctx, list.get(row), e.getKey()));
separator = ", ";
}
@ -531,20 +533,6 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple
ctx.castMode(previous);
}
static final Field<?> patchDefault(Context<?> ctx, Field<?> d, Field<?> f) {
if (NO_SUPPORT_DEFAULT_EXPRESSION.contains(ctx.dialect()))
return patchDefault0(d, f);
return d;
}
static final Field<?> patchDefault0(Field<?> d, Field<?> f) {
if (d instanceof Default)
return orElse(f.getDataType().default_(), () -> DSL.inline(null, f));
return d;
}

View File

@ -80,6 +80,7 @@ import static org.jooq.impl.DSL.name;
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.Default.NO_SUPPORT_DEFAULT_EXPRESSION_INSERT;
import static org.jooq.impl.FieldMapsForInsert.toSQLInsertSelect;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_DEFAULT;