[jOOQ/jOOQ#9879] Support VIRTUAL client side computed columns

This commit is contained in:
Lukas Eder 2022-04-08 17:04:34 +02:00
parent 3291bc007a
commit d3b700685d
7 changed files with 72 additions and 7 deletions

View File

@ -9146,6 +9146,7 @@ public class JavaGenerator extends AbstractGenerator {
null,
null,
null,
null,
baseType
) + ".getArrayDataType()";
}
@ -9163,6 +9164,7 @@ public class JavaGenerator extends AbstractGenerator {
type.isReadonly(),
type.getGeneratedAlwaysAs(),
type.getGenerationOption(),
type.getGenerator(),
type.getDefaultValue(),
type.getQualifiedUserType()
);
@ -9421,6 +9423,7 @@ public class JavaGenerator extends AbstractGenerator {
boolean r,
String g,
GenerationOption go,
String ge,
String d,
Name u
) {
@ -9552,6 +9555,7 @@ public class JavaGenerator extends AbstractGenerator {
// [#5291] Some dialects report valid SQL expresions (e.g. PostgreSQL), others
// report actual values (e.g. MySQL).

View File

@ -56,6 +56,7 @@ import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.DateAsTimestampBinding;
import org.jooq.impl.DefaultDataType;
import org.jooq.impl.EnumConverter;
import org.jooq.impl.QOM.GenerationOption;
import org.jooq.impl.SQLDataType;
import org.jooq.meta.jaxb.CustomType;
import org.jooq.meta.jaxb.ForcedType;
@ -307,8 +308,17 @@ public abstract class AbstractTypedElementDefinition<T extends Definition>
}
}
if (generator != null)
if (generator != null) {
db.markUsed(forcedType);
((DefaultDataTypeDefinition) result).generator(generator);
}
}
return result;

View File

@ -61,6 +61,7 @@ public class DefaultColumnDefinition
private final boolean identity;
private final boolean readonly;
private transient List<EmbeddableDefinition> replacedByEmbeddables;
private boolean synthetic;
public DefaultColumnDefinition(
TableDefinition table,
@ -133,6 +134,16 @@ public class DefaultColumnDefinition
return false;
}
final DefaultColumnDefinition synthetic(boolean s) {
this.synthetic = s;
return this;
}
@Override
public final boolean isSynthetic() {
return synthetic;
}
@Override
public final int getPosition() {
return position;

View File

@ -503,13 +503,41 @@ public interface DataType<T> extends Named {
/**
* Whether this column is computed on the client.
* <p>
* This is true only if {@link #computed()} and
* {@link #generationLocation()} == {@link GenerationLocation#CLIENT}.
* This is true only if all of these hold true:
* <ul>
* <li>{@link #computed()}</li>
* <li>{@link #generationLocation()} == {@link GenerationLocation#CLIENT}</li>
* <p>
* This feature is implemented in commercial distributions only.
*/
boolean computedOnClient();
/**
* Whether this column is computed on the client.
* <p>
* This is true only if all of these hold true:
* <ul>
* <li>{@link #computed()}</li>
* <li>{@link #generationLocation()} == {@link GenerationLocation#CLIENT}</li>
* <li>{@link #generationOption()} == {@link GenerationOption#STORED}</li>
* <p>
* This feature is implemented in commercial distributions only.
*/
boolean computedOnClientStored();
/**
* Whether this column is computed on the client.
* <p>
* This is true only if all of these hold true:
* <ul>
* <li>{@link #computed()}</li>
* <li>{@link #generationLocation()} == {@link GenerationLocation#CLIENT}</li>
* <li>{@link #generationOption()} == {@link GenerationOption#VIRTUAL}</li>
* <p>
* This feature is implemented in commercial distributions only.
*/
boolean computedOnClientVirtual();
/**
* Set the computed column expression of this data type to a constant value.
* <p>

View File

@ -175,6 +175,16 @@ implements
return computed() && generationLocation() == GenerationLocation.CLIENT;
}
@Override
public final boolean computedOnClientStored() {
return computedOnClient() && generationOption() == GenerationOption.STORED;
}
@Override
public final boolean computedOnClientVirtual() {
return computedOnClient() && generationOption() == GenerationOption.VIRTUAL;
}
@Override
public final DataType<T> generatedAlwaysAs(T g) {
return generatedAlwaysAs(Tools.field(g, this));

View File

@ -391,7 +391,7 @@ implements
.visit(K_SET)
.formatIndentStart()
.formatSeparator()
.visit(updateMapComputedOnClient(ctx))
.visit(updateMapComputedOnClientStored(ctx))
.formatIndentEnd();
if (condition.hasWhere())
@ -451,7 +451,7 @@ implements
if (condition.hasWhere())
ctx.data(DATA_ON_DUPLICATE_KEY_WHERE, condition.getWhere());
ctx.visit(updateMapComputedOnClient(ctx));
ctx.visit(updateMapComputedOnClientStored(ctx));
if (condition.hasWhere())
ctx.data().remove(DATA_ON_DUPLICATE_KEY_WHERE);
@ -866,7 +866,7 @@ implements
// not with ON DUPLICATE KEY IGNORE
MergeNotMatchedStep<R> notMatched = on;
if (onDuplicateKeyUpdate) {
final FieldMapForUpdate um = updateMapComputedOnClient(ctx);
final FieldMapForUpdate um = updateMapComputedOnClientStored(ctx);
notMatched = condition.hasWhere()
? on.whenMatchedAnd(condition.getWhere()).thenUpdate().set(um)
@ -881,7 +881,7 @@ implements
return DSL.sql("[ The ON DUPLICATE KEY IGNORE/UPDATE clause cannot be emulated when inserting into non-updatable tables : " + table() + " ]");
}
private final FieldMapForUpdate updateMapComputedOnClient(Context<?> ctx) {
private final FieldMapForUpdate updateMapComputedOnClientStored(Context<?> ctx) {

View File

@ -120,6 +120,8 @@ class TableFieldImpl<R extends Record, T> extends AbstractField<T> implements Ta
ctx.data(DATA_OMIT_CLAUSE_EVENT_EMISSION, true, c -> {