Permalink
Browse files

fix: ensure executeBatch() does not use server-side prepared statemen…

…ts when prepareThreshold=0 (#690)
  • Loading branch information...
scubasau authored and vlsi committed Jan 20, 2017
1 parent faab499 commit aca26a07026e9b289a209799ab28131a33b296dd
@@ -735,7 +735,7 @@ protected BatchResultHandler createBatchHandler(Query[] queries,
// If executing the same query twice in a batch, make sure the statement
// is server-prepared. In other words, "oneshot" only if the query is one in the batch
// or the queries are different
&& isOneShotQuery(null)) {
|| isOneShotQuery(null)) {
flags |= QueryExecutor.QUERY_ONESHOT;
} else {
// If a batch requests generated keys and isn't already described,
@@ -69,4 +69,8 @@ public void assumeCallableStatementsSupported() {
Assume.assumeTrue("callable statements are not fully supported in simple protocol execution mode",
preferQueryMode.compareTo(PreferQueryMode.EXTENDED) >= 0);
}
public void assumeBinaryModeRegular() {
Assume.assumeTrue(binaryMode == BinaryMode.REGULAR);
}
}
@@ -11,10 +11,12 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.postgresql.jdbc.PgStatement;
import org.postgresql.jdbc.PreferQueryMode;
import org.postgresql.test.TestUtil;
import org.postgresql.test.util.BrokenInputStream;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -1063,4 +1065,64 @@ public void testStatementDescribe() throws SQLException {
pstmt.close();
}
@Test
public void testBatchWithPrepareThreshold5() throws SQLException {
assumeBinaryModeRegular();
Assume.assumeTrue("simple protocol only does not support prepared statement requests",
preferQueryMode != PreferQueryMode.SIMPLE);
PreparedStatement pstmt = con.prepareStatement("CREATE temp TABLE batch_tab_threshold5 (id bigint, val bigint)");
pstmt.executeUpdate();
pstmt.close();
// When using a prepareThreshold of 5, a batch update should use server-side prepare
pstmt = con.prepareStatement("INSERT INTO batch_tab_threshold5 (id, val) VALUES (?,?)");
((PgStatement) pstmt).setPrepareThreshold(5);
for (int p = 0; p < 5; p++) {
for (int i = 0; i <= 5; i++) {
pstmt.setLong(1, i);
pstmt.setLong(2, i);
pstmt.addBatch();
}
pstmt.executeBatch();
}
pstmt.close();
pstmt = con.prepareStatement("select count(*) from pg_prepared_statements where statement = 'INSERT INTO batch_tab_threshold5 (id, val) VALUES ($1,$2)'");
ResultSet rs = pstmt.executeQuery();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
rs.close();
pstmt.close();
}
@Test
public void testBatchWithPrepareThreshold0() throws SQLException {
assumeBinaryModeRegular();
Assume.assumeTrue("simple protocol only does not support prepared statement requests",
preferQueryMode != PreferQueryMode.SIMPLE);
PreparedStatement pstmt = con.prepareStatement("CREATE temp TABLE batch_tab_threshold0 (id bigint, val bigint)");
pstmt.executeUpdate();
pstmt.close();
// When using a prepareThreshold of 0, a batch update should not use server-side prepare
pstmt = con.prepareStatement("INSERT INTO batch_tab_threshold0 (id, val) VALUES (?,?)");
((PgStatement) pstmt).setPrepareThreshold(0);
for (int p = 0; p < 5; p++) {
for (int i = 0; i <= 5; i++) {
pstmt.setLong(1, i);
pstmt.setLong(2, i);
pstmt.addBatch();
}
pstmt.executeBatch();
}
pstmt.close();
pstmt = con.prepareStatement("select count(*) from pg_prepared_statements where statement = 'INSERT INTO batch_tab_threshold0 (id, val) VALUES ($1,$2)'");
ResultSet rs = pstmt.executeQuery();
assertTrue(rs.next());
assertEquals(0, rs.getInt(1));
rs.close();
pstmt.close();
}
}

0 comments on commit aca26a0

Please sign in to comment.