diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java index ead2300628..3e95bd4f9a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java @@ -68,7 +68,9 @@ import static org.jooq.SQLDialect.POSTGRES; // ... import static org.jooq.conf.SettingsTools.renderLocale; import static org.jooq.impl.CommonTableExpressionList.markTopLevelCteAndAccept; +import static org.jooq.impl.DSL.finalTable; import static org.jooq.impl.DSL.name; +import static org.jooq.impl.DSL.oldTable; import static org.jooq.impl.DSL.select; import static org.jooq.impl.DSL.unquotedName; import static org.jooq.impl.Keywords.K_BEGIN; @@ -128,6 +130,7 @@ import org.jooq.CommonTableExpression; import org.jooq.Condition; import org.jooq.Configuration; import org.jooq.Context; +import org.jooq.DMLQuery; import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.Delete; @@ -171,7 +174,8 @@ import org.jetbrains.annotations.NotNull; /** * @author Lukas Eder */ -abstract class AbstractDMLQuery extends AbstractRowCountQuery { +abstract class AbstractDMLQuery extends AbstractRowCountQuery implements DMLQuery { + private static final JooqLogger log = JooqLogger.getLogger(AbstractQuery.class); private static final Set NO_SUPPORT_INSERT_ALIASED_TABLE = SQLDialect.supportedBy(DERBY, FIREBIRD, H2, MARIADB, MYSQL); @@ -631,6 +635,8 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery + + diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 75da8f1d4b..2df926e062 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -211,6 +211,7 @@ import org.jooq.ConstraintTypeStep; import org.jooq.CreateTableColumnStep; import org.jooq.CreateTypeStep; import org.jooq.CreateViewAsStep; +import org.jooq.DMLQuery; import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.DatePart; @@ -432,6 +433,7 @@ import org.jooq.XMLTablePassingStep; import org.jooq.conf.NestedCollectionEmulation; import org.jooq.conf.Settings; import org.jooq.exception.SQLDialectNotSupportedException; +import org.jooq.impl.DataChangeDeltaTable.ResultOption; import org.jooq.impl.XMLParse.DocumentOrContent; import org.jooq.tools.StringUtils; import org.jooq.tools.jdbc.JDBCUtils; @@ -10887,6 +10889,48 @@ public class DSL { return new RoleImpl(name); } + // ------------------------------------------------------------------------- + // XXX Data Change Delta Table + // ------------------------------------------------------------------------- + + /** + * Get the data change delta table with result option OLD to + * retrieve the modified data from before the {@link Update} or + * {@link Delete} statement was applied. + */ + @NotNull + @Support({ H2, POSTGRES }) + public static Table oldTable(DMLQuery query) { + return new DataChangeDeltaTable<>(ResultOption.OLD, query); + } + + /** + * Get the data change delta table with result option NEW to + * retrieve the modified data from after the {@link Update} or + * {@link Insert} statement was applied. + *

+ * This does not include trigger generated values. + */ + @NotNull + @Support({ H2, POSTGRES }) + public static Table newTable(DMLQuery query) { + return new DataChangeDeltaTable(ResultOption.NEW, query); + } + + + /** + * Get the data change delta table with result option NEW to + * retrieve the modified data from after the {@link Update} or + * {@link Insert} statement was applied. + *

+ * This includes trigger generated values. + */ + @NotNull + @Support({ H2, POSTGRES }) + public static Table finalTable(DMLQuery query) { + return new DataChangeDeltaTable<>(ResultOption.FINAL, query); + } + // ------------------------------------------------------------------------- // XXX Conversion of objects into tables // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java b/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java index b822987d92..a2eb289bfb 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/DataChangeDeltaTable.java @@ -39,35 +39,85 @@ package org.jooq.impl; +import static org.jooq.impl.Keywords.K_FINAL; +import static org.jooq.impl.Keywords.K_NEW; +import static org.jooq.impl.Keywords.K_OLD; +import static org.jooq.impl.Keywords.K_TABLE; +import static org.jooq.impl.Tools.abstractDMLQuery; + +import org.jooq.Context; +import org.jooq.DMLQuery; +import org.jooq.Delete; +import org.jooq.Insert; +import org.jooq.Merge; +import org.jooq.Record; +import org.jooq.Table; +import org.jooq.TableOptions; +import org.jooq.Update; +/** + * @author Lukas Eder + */ +final class DataChangeDeltaTable extends AbstractTable { + private final ResultOption result; + private final DMLQuery query; + private final Table table; + DataChangeDeltaTable(ResultOption result, DMLQuery query) { + super(TableOptions.expression(), table(query).getUnqualifiedName()); + this.result = result; + this.query = query; + this.table = table(query); + } + enum ResultOption { + FINAL, OLD, NEW + } + @SuppressWarnings({ "rawtypes", "unchecked" }) + private static final Table table(DMLQuery query) { + if (query instanceof Insert || query instanceof Update || query instanceof Delete) + return (Table) abstractDMLQuery(query).table(); + else if (query instanceof Merge) + return ((MergeImpl) query).table(); + else + throw new IllegalStateException("Unsupported query type: " + query); + } + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + @Override + public final void accept(Context ctx) { + switch (result) { + case FINAL: ctx.visit(K_FINAL); break; + case OLD: ctx.visit(K_OLD); break; + case NEW: ctx.visit(K_NEW); break; + default: throw new IllegalStateException("Unsupported result option: " + result); + } + ctx.sql(' ').visit(K_TABLE) + .sqlIndentStart(" (") + .visit(query) + .sqlIndentEnd(')'); + } + // ------------------------------------------------------------------------- + // XXX: Table API + // ------------------------------------------------------------------------- + @Override + public final Class getRecordType() { + return table.getRecordType(); + } - - - - - - - - - - - - - - - - - - - + @SuppressWarnings("unchecked") + @Override + final FieldsImpl fields0() { + return ((AbstractRow) table.fieldsRow()).fields; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java index 578b95301d..5ad749dc90 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java @@ -297,32 +297,36 @@ implements // UPSERT API // ------------------------------------------------------------------------- - QueryPartList> getUpsertFields() { + final Table table() { + return table; + } + + final QueryPartList> getUpsertFields() { if (upsertFields == null) upsertFields = new QueryPartList<>(table.fields()); return upsertFields; } - QueryPartList> getUpsertKeys() { + final QueryPartList> getUpsertKeys() { if (upsertKeys == null) upsertKeys = new QueryPartList<>(); return upsertKeys; } - QueryPartList> getUpsertValues() { + final QueryPartList> getUpsertValues() { if (upsertValues == null) upsertValues = new QueryPartList<>(); return upsertValues; } - MatchedClause getLastMatched() { + final MatchedClause getLastMatched() { return matched.get(matched.size() - 1); } - NotMatchedClause getLastNotMatched() { + final NotMatchedClause getLastNotMatched() { return notMatched.get(notMatched.size() - 1); } @@ -343,133 +347,133 @@ implements @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1) { + public final MergeImpl columns(Field field1) { return columns(Arrays.asList(field1)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2) { + public final MergeImpl columns(Field field1, Field field2) { return columns(Arrays.asList(field1, field2)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3) { + public final MergeImpl columns(Field field1, Field field2, Field field3) { return columns(Arrays.asList(field1, field2, field3)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4) { return columns(Arrays.asList(field1, field2, field3, field4)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5) { return columns(Arrays.asList(field1, field2, field3, field4, field5)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20, Field field21) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20, Field field21) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21)); } @Override @SuppressWarnings("hiding") - public MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20, Field field21, Field field22) { + public final MergeImpl columns(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16, Field field17, Field field18, Field field19, Field field20, Field field21, Field field22) { return columns(Arrays.asList(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21, field22)); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index f849c2f752..6a9e47807b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -248,6 +248,7 @@ import org.jooq.Context; import org.jooq.Converter; import org.jooq.ConverterProvider; import org.jooq.Cursor; +import org.jooq.DMLQuery; import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.EmbeddableRecord;