From d3b700685dd2dfb974759e9c5b5b2face8827e1c Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 8 Apr 2022 17:04:34 +0200 Subject: [PATCH] [jOOQ/jOOQ#9879] Support VIRTUAL client side computed columns --- .../java/org/jooq/codegen/JavaGenerator.java | 4 +++ .../meta/AbstractTypedElementDefinition.java | 12 ++++++- .../jooq/meta/DefaultColumnDefinition.java | 11 +++++++ jOOQ/src/main/java/org/jooq/DataType.java | 32 +++++++++++++++++-- .../java/org/jooq/impl/AbstractDataType.java | 10 ++++++ .../java/org/jooq/impl/InsertQueryImpl.java | 8 ++--- .../java/org/jooq/impl/TableFieldImpl.java | 2 ++ 7 files changed, 72 insertions(+), 7 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index 9af0383a7d..836b8f0c2c 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -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). diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java index 812f7a64cf..2e02ea9e60 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java @@ -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 } } - if (generator != null) + if (generator != null) { + db.markUsed(forcedType); ((DefaultDataTypeDefinition) result).generator(generator); + + + + + + + + } } return result; diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java index 2a5fa362b7..8fb2969d10 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java @@ -61,6 +61,7 @@ public class DefaultColumnDefinition private final boolean identity; private final boolean readonly; private transient List 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; diff --git a/jOOQ/src/main/java/org/jooq/DataType.java b/jOOQ/src/main/java/org/jooq/DataType.java index dcb6f0a55b..5e8ecbb17f 100644 --- a/jOOQ/src/main/java/org/jooq/DataType.java +++ b/jOOQ/src/main/java/org/jooq/DataType.java @@ -503,13 +503,41 @@ public interface DataType extends Named { /** * Whether this column is computed on the client. *

- * This is true only if {@link #computed()} and - * {@link #generationLocation()} == {@link GenerationLocation#CLIENT}. + * This is true only if all of these hold true: + *

    + *
  • {@link #computed()}
  • + *
  • {@link #generationLocation()} == {@link GenerationLocation#CLIENT}
  • *

    * This feature is implemented in commercial distributions only. */ boolean computedOnClient(); + /** + * Whether this column is computed on the client. + *

    + * This is true only if all of these hold true: + *

      + *
    • {@link #computed()}
    • + *
    • {@link #generationLocation()} == {@link GenerationLocation#CLIENT}
    • + *
    • {@link #generationOption()} == {@link GenerationOption#STORED}
    • + *

      + * This feature is implemented in commercial distributions only. + */ + boolean computedOnClientStored(); + + /** + * Whether this column is computed on the client. + *

      + * This is true only if all of these hold true: + *

        + *
      • {@link #computed()}
      • + *
      • {@link #generationLocation()} == {@link GenerationLocation#CLIENT}
      • + *
      • {@link #generationOption()} == {@link GenerationOption#VIRTUAL}
      • + *

        + * This feature is implemented in commercial distributions only. + */ + boolean computedOnClientVirtual(); + /** * Set the computed column expression of this data type to a constant value. *

        diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java index 2a17349a77..9ee7538c29 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java @@ -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 generatedAlwaysAs(T g) { return generatedAlwaysAs(Tools.field(g, this)); diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index 3439510f6f..08b9d38c69 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -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 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) { diff --git a/jOOQ/src/main/java/org/jooq/impl/TableFieldImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableFieldImpl.java index c6c4060595..7c28d47a48 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableFieldImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableFieldImpl.java @@ -120,6 +120,8 @@ class TableFieldImpl extends AbstractField implements Ta + + ctx.data(DATA_OMIT_CLAUSE_EVENT_EMISSION, true, c -> {