diff --git a/jOOQ/src/main/java/org/jooq/DeleteQuery.java b/jOOQ/src/main/java/org/jooq/DeleteQuery.java index 000d4bdb9e..fb719a2774 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteQuery.java +++ b/jOOQ/src/main/java/org/jooq/DeleteQuery.java @@ -42,6 +42,7 @@ package org.jooq; // ... // ... import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.MARIADB; // ... import static org.jooq.SQLDialect.POSTGRES; @@ -153,7 +154,7 @@ public interface DeleteQuery extends ConditionProvider, Delete * * @see #getReturnedRecords() */ - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) void setReturning(); /** @@ -163,7 +164,7 @@ public interface DeleteQuery extends ConditionProvider, Delete * @param fields Fields to be returned * @see #getReturnedRecords() */ - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) void setReturning(SelectFieldOrAsterisk... fields); /** @@ -173,7 +174,7 @@ public interface DeleteQuery extends ConditionProvider, Delete * @param fields Fields to be returned * @see #getReturnedRecords() */ - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) void setReturning(Collection fields); /** @@ -196,7 +197,7 @@ public interface DeleteQuery extends ConditionProvider, Delete * @see #getReturnedRecords() */ @Nullable - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) R getReturnedRecord(); /** @@ -222,7 +223,7 @@ public interface DeleteQuery extends ConditionProvider, Delete * */ @NotNull - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) Result getReturnedRecords(); } diff --git a/jOOQ/src/main/java/org/jooq/DeleteResultStep.java b/jOOQ/src/main/java/org/jooq/DeleteResultStep.java index 5c648250e9..5f577e0a1d 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteResultStep.java +++ b/jOOQ/src/main/java/org/jooq/DeleteResultStep.java @@ -41,6 +41,7 @@ package org.jooq; // ... // ... import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.MARIADB; // ... import static org.jooq.SQLDialect.POSTGRES; // ... @@ -110,7 +111,7 @@ public interface DeleteResultStep extends Delete { * @see DeleteQuery#getReturnedRecords() */ @NotNull - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) Result fetch() throws DataAccessException; /** @@ -126,7 +127,7 @@ public interface DeleteResultStep extends Delete { * @see DeleteQuery#getReturnedRecord() */ @Nullable - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) R fetchOne() throws DataAccessException, TooManyRowsException; @@ -141,7 +142,7 @@ public interface DeleteResultStep extends Delete { * @see DeleteQuery#getReturnedRecord() */ @NotNull - @Support({ FIREBIRD, POSTGRES }) + @Support({ FIREBIRD, MARIADB, POSTGRES }) Optional fetchOptional() throws DataAccessException, TooManyRowsException; } diff --git a/jOOQ/src/main/java/org/jooq/DeleteReturningStep.java b/jOOQ/src/main/java/org/jooq/DeleteReturningStep.java index 043ee25a97..c28b294312 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteReturningStep.java +++ b/jOOQ/src/main/java/org/jooq/DeleteReturningStep.java @@ -37,19 +37,19 @@ */ package org.jooq; -import org.jetbrains.annotations.*; - - // ... // ... // ... import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.MARIADB; // ... import static org.jooq.SQLDialect.POSTGRES; // ... import java.util.Collection; +import org.jetbrains.annotations.NotNull; + /** * This type is used for the {@link Delete}'s DSL API. *

@@ -100,7 +100,7 @@ public interface DeleteReturningStep extends DeleteFinalStep returning(); /** @@ -119,7 +119,7 @@ public interface DeleteReturningStep extends DeleteFinalStep returning(SelectFieldOrAsterisk... fields); /** @@ -138,7 +138,7 @@ public interface DeleteReturningStep extends DeleteFinalStep returning(Collection fields); /** @@ -151,7 +151,7 @@ public interface DeleteReturningStep extends DeleteFinalStep returningResult(SelectFieldOrAsterisk... fields); /** @@ -164,7 +164,7 @@ public interface DeleteReturningStep extends DeleteFinalStep returningResult(Collection fields); @@ -178,7 +178,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1); /** @@ -190,7 +190,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2); /** @@ -202,7 +202,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3); /** @@ -214,7 +214,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4); /** @@ -226,7 +226,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5); /** @@ -238,7 +238,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6); /** @@ -250,7 +250,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7); /** @@ -262,7 +262,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8); /** @@ -274,7 +274,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9); /** @@ -286,7 +286,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10); /** @@ -298,7 +298,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11); /** @@ -310,7 +310,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12); /** @@ -322,7 +322,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13); /** @@ -334,7 +334,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14); /** @@ -346,7 +346,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15); /** @@ -358,7 +358,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16); /** @@ -370,7 +370,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17); /** @@ -382,7 +382,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17, SelectField field18); /** @@ -394,7 +394,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17, SelectField field18, SelectField field19); /** @@ -406,7 +406,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17, SelectField field18, SelectField field19, SelectField field20); /** @@ -418,7 +418,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17, SelectField field18, SelectField field19, SelectField field20, SelectField field21); /** @@ -430,7 +430,7 @@ public interface DeleteReturningStep extends DeleteFinalStep DeleteResultStep> returningResult(SelectField field1, SelectField field2, SelectField field3, SelectField field4, SelectField field5, SelectField field6, SelectField field7, SelectField field8, SelectField field9, SelectField field10, SelectField field11, SelectField field12, SelectField field13, SelectField field14, SelectField field15, SelectField field16, SelectField field17, SelectField field18, SelectField field19, SelectField field20, SelectField field21, SelectField field22); diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java index b7d46c3000..edcc81f5fc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDMLQuery.java @@ -42,6 +42,8 @@ import static java.lang.Boolean.TRUE; // ... // ... // ... +// ... +// ... import static org.jooq.SQLDialect.DERBY; import static org.jooq.SQLDialect.FIREBIRD; import static org.jooq.SQLDialect.H2; @@ -50,9 +52,12 @@ import static org.jooq.SQLDialect.HSQLDB; // ... import static org.jooq.SQLDialect.MARIADB; // ... +// ... +// ... import static org.jooq.SQLDialect.MYSQL; // ... // ... +import static org.jooq.SQLDialect.POSTGRES; // ... // ... // ... @@ -122,10 +127,12 @@ import org.jooq.QualifiedAsterisk; import org.jooq.Record; import org.jooq.Result; import org.jooq.SQLDialect; +import org.jooq.Scope; import org.jooq.Select; import org.jooq.SelectFieldOrAsterisk; import org.jooq.Table; import org.jooq.UniqueKey; +import org.jooq.Update; import org.jooq.conf.ExecuteWithoutWhere; import org.jooq.conf.RenderNameCase; import org.jooq.conf.SettingsTools; @@ -147,6 +154,10 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery 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); + private static final Set NATIVE_SUPPORT_INSERT_RETURNING = SQLDialect.supportedBy(FIREBIRD, MARIADB, POSTGRES); + private static final Set NATIVE_SUPPORT_UPDATE_RETURNING = SQLDialect.supportedBy(FIREBIRD, POSTGRES); + private static final Set NATIVE_SUPPORT_DELETE_RETURNING = SQLDialect.supportedBy(FIREBIRD, MARIADB, POSTGRES); + @@ -758,40 +769,48 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery - - final void toSQLReturning(Context ctx) { if (!returning.isEmpty()) { - switch (ctx.family()) { + // Other dialects don't render a RETURNING clause, but + // use JDBC's Statement.RETURN_GENERATED_KEYS mode instead + if (nativeSupportReturning(ctx)) { + boolean declareFields = ctx.declareFields(); + boolean qualify = ctx.qualify(); + boolean unqualify = ctx.family() == MARIADB; + if (unqualify) + ctx.qualify(false); + ctx.formatSeparator() + .visit(K_RETURNING) + .sql(' ') + .declareFields(true) - case FIREBIRD: - case POSTGRES: { - boolean previous = ctx.declareFields(); + .visit( - ctx.formatSeparator() - .visit(K_RETURNING) - .sql(' ') - .declareFields(true) - .visit(ctx.family() == FIREBIRD ? new SelectFieldList<>(returningResolvedAsterisks) : returning) - .declareFields(previous); + // Firebird doesn't support asterisks at all here + // MariaDB doesn't support qualified asterisks: https://jira.mariadb.org/browse/MDEV-23178 + ctx.family() == FIREBIRD || ctx.family() == MARIADB + ? new SelectFieldList<>(returningResolvedAsterisks) + : returning + ) + .declareFields(declareFields); - break; - } - - default: - // Other dialects don't render a RETURNING clause, but - // use JDBC's Statement.RETURN_GENERATED_KEYS mode instead - break; + if (unqualify) + ctx.qualify(qualify); } } } + private final boolean nativeSupportReturning(Scope ctx) { + return this instanceof Insert && NATIVE_SUPPORT_INSERT_RETURNING.contains(ctx.dialect()) + || this instanceof Update && NATIVE_SUPPORT_UPDATE_RETURNING.contains(ctx.dialect()) + || this instanceof Delete && NATIVE_SUPPORT_DELETE_RETURNING.contains(ctx.dialect()); + } @Override protected final void prepare(ExecuteContext ctx) throws SQLException { @@ -799,7 +818,7 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery Tools.setFetchSize(ctx, 0); } - private void prepare0(ExecuteContext ctx) throws SQLException { + private final void prepare0(ExecuteContext ctx) throws SQLException { Connection connection = ctx.connection(); @@ -810,10 +829,8 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery - if (returning.isEmpty()) { super.prepare(ctx); - return; } @@ -823,8 +840,9 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery - - // Values should be returned from the INSERT + else if (nativeSupportReturning(ctx)) { + super.prepare(ctx); + } else { switch (ctx.family()) { @@ -836,15 +854,9 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery - - - // Postgres uses the RETURNING clause in SQL - case FIREBIRD: - case POSTGRES: // SQLite will select last_insert_rowid() after the INSER case SQLITE: case CUBRID: - super.prepare(ctx); break; @@ -861,8 +873,12 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery + case DERBY: case H2: + + // [#9212] Older MariaDB versions that don't support RETURNING + // yet, or UPDATE .. RETURNING case MARIADB: case MYSQL: ctx.statement(connection.prepareStatement(ctx.sql(), Statement.RETURN_GENERATED_KEYS)); @@ -999,11 +1015,18 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery case DERBY: case H2: - case MARIADB: case MYSQL: { return executeReturningGeneratedKeysFetchAdditionalRows(ctx, listener); } + case MARIADB: { + if (!nativeSupportReturning(ctx)) + return executeReturningGeneratedKeysFetchAdditionalRows(ctx, listener); + + rs = executeReturningQuery(ctx, listener); + break; + } + @@ -1245,7 +1268,7 @@ abstract class AbstractDMLQuery extends AbstractRowCountQuery } } - private Field returnedIdentity() { + private final Field returnedIdentity() { if (table.getIdentity() != null) return table.getIdentity().getField(); else diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index e534228d07..43e307dd58 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -1322,11 +1322,27 @@ final class Tools { Field[] result = new Field[fields.length]; for (int i = 0; i < fields.length; i++) - result[i] = DSL.field(fields[i].getUnqualifiedName(), fields[i].getDataType()); + result[i] = unqualified(fields[i]); return result; } + static final List> unqualified(Collection> fields) { + if (fields == null) + return null; + + List> result = new ArrayList<>(fields.size()); + + for (Field field : fields) + result.add(unqualified(field)); + + return result; + } + + static final Field unqualified(Field field) { + return DSL.field(field.getUnqualifiedName(), field.getDataType()); + } + static final Name[] unqualifiedNames(Field[] fields) { if (fields == null) return null;