[jOOQ/jOOQ#16409] Improve Javadoc and log DEBUG message on RETURNING clauses, stressing that they can't return any rows for tables without identity in some dialects
This commit is contained in:
parent
71e1a06781
commit
46c0a3760f
@ -56,20 +56,34 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* This type is used for the {@link Delete}'s DSL API.
|
||||
* <p>
|
||||
* Example: <pre><code>
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* DSLContext create = DSL.using(configuration);
|
||||
*
|
||||
* create.delete(table)
|
||||
* .where(field1.greaterThan(100))
|
||||
* .execute();
|
||||
* </code></pre>
|
||||
* </code>
|
||||
* </pre>
|
||||
* <p>
|
||||
* This implemented differently for every dialect:
|
||||
* <ul>
|
||||
* <li>Firebird and Postgres have native support for
|
||||
* <code>UPDATE … RETURNING</code> clauses</li>
|
||||
* <li>DB2 allows to execute
|
||||
* <li>{@link SQLDialect#COCKROACHDB} {@link SQLDialect#FIREBIRD},
|
||||
* {@link SQLDialect#MARIADB}, {@link SQLDialect#POSTGRES},
|
||||
* {@link SQLDialect#SQLITE}, {@link SQLDialect#YUGABYTEDB} have native support
|
||||
* for <code>DELETE … RETURNING</code> clauses in SQL</li>
|
||||
* <li>{@link SQLDialect#ORACLE} has native support for
|
||||
* <code>DELETE … RETURNING</code> in PL/SQL, so jOOQ can render an anonymous
|
||||
* block</li>
|
||||
* <li>{@link SQLDialect#SQLSERVER} supports an <code>DELETE … OUTPUT</code>
|
||||
* syntax, which can capture defaults and computed column values, though not
|
||||
* trigger generated values.</li>
|
||||
* <li>{@link SQLDialect#DB2} and {@link SQLDialect#H2} allow to execute the
|
||||
* standard SQL data change delta table syntax:
|
||||
* <code>SELECT … FROM FINAL TABLE (DELETE …)</code></li>
|
||||
* <li>Other dialects cannot emulate <code>DELETE … RETURNING</code>.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
|
||||
@ -39,13 +39,16 @@ package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This type is used for the {@link Insert}'s DSL API.
|
||||
* <p>
|
||||
* Example: <pre><code>
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* DSLContext create = DSL.using(configuration);
|
||||
*
|
||||
* TableRecord<?> record =
|
||||
@ -53,27 +56,38 @@ import java.util.Collection;
|
||||
* .values(value1, value2)
|
||||
* .returning(field1)
|
||||
* .fetchOne();
|
||||
* </code></pre>
|
||||
* </code>
|
||||
* </pre>
|
||||
* <p>
|
||||
* This implemented differently for every dialect:
|
||||
* <ul>
|
||||
* <li>Firebird and Postgres have native support for
|
||||
* <code>INSERT … RETURNING</code> clauses</li>
|
||||
* <li>DB2 allows to execute
|
||||
* <code>SELECT … FROM FINAL TABLE (INSERT …)</code></li>
|
||||
* <li>HSQLDB, and Oracle JDBC drivers allow for retrieving any table column as
|
||||
* "generated key" in one statement</li>
|
||||
* <li>Derby, H2, Ingres, MySQL, SQL Server only allow for retrieving IDENTITY
|
||||
* column values as "generated key". If other fields are requested, a second
|
||||
* statement is issued. Client code must assure transactional integrity between
|
||||
* the two statements.</li>
|
||||
* <li>Sybase and SQLite allow for retrieving IDENTITY values as
|
||||
* <code>@@identity</code> or <code>last_inserted_rowid()</code> values. Those
|
||||
* values are fetched in a separate <code>SELECT</code> statement. If other
|
||||
* fields are requested, a second statement is issued. Client code must assure
|
||||
* transactional integrity between the two statements.</li>
|
||||
* <li>{@link SQLDialect#COCKROACHDB}, {@link SQLDialect#DUCKDB},
|
||||
* {@link SQLDialect#FIREBIRD}, {@link SQLDialect#MARIADB},
|
||||
* {@link SQLDialect#POSTGRES}, {@link SQLDialect#SQLITE},
|
||||
* {@link SQLDialect#YUGABYTEDB} have native support for
|
||||
* <code>UPDATE … RETURNING</code> clauses in SQL</li>
|
||||
* <li>{@link SQLDialect#ORACLE} has native support for
|
||||
* <code>UPDATE … RETURNING</code> in PL/SQL, so jOOQ can render an anonymous
|
||||
* block</li>
|
||||
* <li>{@link SQLDialect#SQLSERVER} supports an <code>UPDATE … OUTPUT</code>
|
||||
* syntax, which can capture defaults and computed column values, though not
|
||||
* trigger generated values.</li>
|
||||
* <li>{@link SQLDialect#DB2} and {@link SQLDialect#H2} allow to execute the
|
||||
* standard SQL data change delta table syntax:
|
||||
* <code>SELECT … FROM FINAL TABLE (UPDATE …)</code></li>
|
||||
* <li>Other dialects may be able to retrieve <code>IDENTITY</code> values using
|
||||
* JDBC {@link Statement#RETURN_GENERATED_KEYS} or using native SQL means, such
|
||||
* as <code>@@identity</code> or similar variables, and other fields using a
|
||||
* second query, in case of which clients will need to ensure transactional
|
||||
* integrity themselves.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <strong>Note that if jOOQ cannot fetch any identity value in your given
|
||||
* dialect because 1) there is no native SQL syntax or 2) there is no identity
|
||||
* column, or 3) there is no support for fetching any identity values, then the
|
||||
* <code>INSERT … RETURNING</code> statement will simply not produce any
|
||||
* rows!</strong>
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
|
||||
@ -56,7 +56,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* This type is used for the {@link Update}'s DSL API.
|
||||
* <p>
|
||||
* Example: <pre><code>
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* DSLContext create = DSL.using(configuration);
|
||||
*
|
||||
* TableRecord<?> record =
|
||||
@ -65,14 +68,25 @@ import org.jetbrains.annotations.NotNull;
|
||||
* .set(field2, value2)
|
||||
* .returning(field1)
|
||||
* .fetchOne();
|
||||
* </code></pre>
|
||||
* </code>
|
||||
* </pre>
|
||||
* <p>
|
||||
* This implemented differently for every dialect:
|
||||
* <ul>
|
||||
* <li>Firebird and Postgres have native support for
|
||||
* <code>UPDATE … RETURNING</code> clauses</li>
|
||||
* <li>DB2 allows to execute
|
||||
* <li>{@link SQLDialect#COCKROACHDB}, {@link SQLDialect#FIREBIRD},
|
||||
* {@link SQLDialect#MARIADB}, {@link SQLDialect#POSTGRES},
|
||||
* {@link SQLDialect#SQLITE}, {@link SQLDialect#YUGABYTEDB} have native support
|
||||
* for <code>UPDATE … RETURNING</code> clauses in SQL</li>
|
||||
* <li>{@link SQLDialect#ORACLE} has native support for
|
||||
* <code>UPDATE … RETURNING</code> in PL/SQL, so jOOQ can render an anonymous
|
||||
* block</li>
|
||||
* <li>{@link SQLDialect#SQLSERVER} supports an <code>UPDATE … OUTPUT</code>
|
||||
* syntax, which can capture defaults and computed column values, though not
|
||||
* trigger generated values.</li>
|
||||
* <li>{@link SQLDialect#DB2} and {@link SQLDialect#H2} allow to execute the
|
||||
* standard SQL data change delta table syntax:
|
||||
* <code>SELECT … FROM FINAL TABLE (UPDATE …)</code></li>
|
||||
* <li>Other dialects cannot emulate <code>UPDATE … RETURNING</code>.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
|
||||
@ -1113,6 +1113,7 @@ abstract class AbstractDMLQuery<R extends Record> extends AbstractRowCountQuery
|
||||
}
|
||||
// Column stores don't seem support fetching generated keys
|
||||
else if (NO_SUPPORT_FETCHING_KEYS.contains(ctx.dialect())) {
|
||||
log.debug("RETURNING was set on query, but dialect doesn't support fetching generated keys: " + ctx.dialect());
|
||||
return super.execute(ctx, listener);
|
||||
}
|
||||
else {
|
||||
@ -1135,6 +1136,7 @@ abstract class AbstractDMLQuery<R extends Record> extends AbstractRowCountQuery
|
||||
.fetch();
|
||||
|
||||
returnedResult.attach(((DefaultExecuteContext) ctx).originalConfiguration());
|
||||
logOnEmptyReturned(ctx);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
@ -1344,6 +1346,11 @@ abstract class AbstractDMLQuery<R extends Record> extends AbstractRowCountQuery
|
||||
}
|
||||
}
|
||||
|
||||
private final void logOnEmptyReturned(Scope ctx) {
|
||||
if (estimatedRowCount(ctx) == 1)
|
||||
log.debug("RETURNING was set on query, but no rows were returned. This is likely due to a missing identity column (or an identity column unknown to jOOQ).");
|
||||
}
|
||||
|
||||
private final int executeReturningGeneratedKeys(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
|
||||
listener.executeStart(ctx);
|
||||
int result = executeImmediate(ctx.statement()).executeUpdate();
|
||||
@ -1459,6 +1466,8 @@ abstract class AbstractDMLQuery<R extends Record> extends AbstractRowCountQuery
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
logOnEmptyReturned(derivedConfiguration.dsl());
|
||||
}
|
||||
|
||||
private final Field<?> returnedIdentity() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user