Skip to content

Commit

Permalink
[#5666] Prevent multiple calls to Statement.getUpdateCount(), which i…
Browse files Browse the repository at this point in the history
…s against the JDBC spec
  • Loading branch information
lukaseder committed Feb 8, 2017
1 parent 2dde24c commit 6b0888a
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 51 deletions.
44 changes: 3 additions & 41 deletions jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java
Expand Up @@ -38,15 +38,14 @@
import static java.sql.ResultSet.TYPE_SCROLL_SENSITIVE;
import static java.util.Arrays.asList;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.POSTGRES;
// ...
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.Tools.blocking;
import static org.jooq.impl.Tools.consumeResultSets;
import static org.jooq.impl.Tools.executeStatementAndGetFirstResultSet;
import static org.jooq.impl.Tools.DataKey.DATA_LOCK_ROWS_FOR_UPDATE;

import java.lang.reflect.Array;
Expand Down Expand Up @@ -252,49 +251,12 @@ else if (isForUpdate() && asList(CUBRID).contains(ctx.configuration().dialect().
protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
listener.executeStart(ctx);

// [#5666] Avoid calling Statement.getUpdateCount() twice
Integer updateCount = null;

// [#4511] [#4753] PostgreSQL doesn't like fetchSize with autoCommit == true
int f = SettingsTools.getFetchSize(fetchSize, ctx.settings());
if (ctx.family() == POSTGRES && f != 0 && ctx.connection().getAutoCommit())
log.info("Fetch Size", "A fetch size of " + f + " was set on a auto-commit PostgreSQL connection, which is not recommended. See http://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor");
































if (ctx.statement().execute()) {
ctx.resultSet(ctx.statement().getResultSet());
}

executeStatementAndGetFirstResultSet(ctx);
listener.executeEnd(ctx);

// Fetch a single result set
Expand All @@ -309,7 +271,7 @@ protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws
DSLContext dsl = DSL.using(ctx.configuration());
Field<Integer> c = field(name("UPDATE_COUNT"), int.class);
Result<Record1<Integer>> r = dsl.newResult(c);
r.add(dsl.newRecord(c).values(updateCount != null ? updateCount : ctx.statement().getUpdateCount()));
r.add(dsl.newRecord(c).values(ctx.rows()));
ctx.resultSet(new MockResultSet(r));
}

Expand Down
6 changes: 2 additions & 4 deletions jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java
Expand Up @@ -50,6 +50,7 @@
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.EMPTY_STRING;
import static org.jooq.impl.Tools.consumeExceptions;
import static org.jooq.impl.Tools.executeStatementAndGetFirstResultSet;
import static org.jooq.impl.Tools.settings;

import java.sql.CallableStatement;
Expand Down Expand Up @@ -471,10 +472,7 @@ private final int executeCallableStatement() {
private final void execute0(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
try {
listener.executeStart(ctx);

if (ctx.statement().execute())
ctx.resultSet(ctx.statement().getResultSet());

executeStatementAndGetFirstResultSet(ctx);
listener.executeEnd(ctx);
}

Expand Down
80 changes: 74 additions & 6 deletions jOOQ/src/main/java/org/jooq/impl/Tools.java
Expand Up @@ -38,9 +38,11 @@
import static java.lang.Character.isJavaIdentifierPart;
import static java.util.Arrays.asList;
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.MARIADB;
import static org.jooq.SQLDialect.MYSQL;
// ...
import static org.jooq.conf.BackslashEscaping.DEFAULT;
import static org.jooq.conf.BackslashEscaping.ON;
import static org.jooq.conf.ParamType.INLINED;
Expand Down Expand Up @@ -2901,13 +2903,73 @@ static final void consumeWarnings(ExecuteContext ctx, ExecuteListener listener)
listener.warning(ctx);
}

/**
* [#5666] Handle the complexity of each dialect's understanding of
* correctly calling {@link Statement#execute()}.
*/
static final void executeStatementAndGetFirstResultSet(ExecuteContext ctx) throws SQLException {
PreparedStatement stmt = ctx.statement();












































if (stmt.execute()) {
ctx.resultSet(stmt.getResultSet());
}

else {
ctx.resultSet(null);
ctx.rows(stmt.getUpdateCount());
}
}

/**
* [#3681] Consume all {@link ResultSet}s from a JDBC {@link Statement}.
*/
static final void consumeResultSets(ExecuteContext ctx, ExecuteListener listener, Results results, Intern intern) throws SQLException {
boolean anyResults = false;
int i = 0;
int rows = (ctx.resultSet() == null) ? ctx.statement().getUpdateCount() : 0;
int rows = (ctx.resultSet() == null) ? ctx.rows() : 0;

for (i = 0; i < maxConsumedResults; i++) {
if (ctx.resultSet() != null) {
Expand All @@ -2924,12 +2986,18 @@ static final void consumeResultSets(ExecuteContext ctx, ExecuteListener listener
break;
}

if (ctx.statement().getMoreResults())
if (ctx.statement().getMoreResults()) {
ctx.resultSet(ctx.statement().getResultSet());
else if ((rows = ctx.statement().getUpdateCount()) != -1)
ctx.resultSet(null);
else
break;
}
else {
rows = ctx.statement().getUpdateCount();
ctx.rows(rows);

if (rows != -1)
ctx.resultSet(null);
else
break;
}
}

if (i == maxConsumedResults)
Expand Down

0 comments on commit 6b0888a

Please sign in to comment.