diff --git a/CHANGES b/CHANGES index 4858c88ca..f2180e408 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 8.4.0 + - Fix for Bug#113129 (Bug#36043145), setting the FetchSize on a Statement object does not affect. + - Fix for Bug#22931632, GETPARAMETERBINDINGS() ON A PS RETURNS NPE WHEN NOT ALL PARAMETERS ARE BOUND. - WL#16147, Remove support for FIDO authentication. diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetFactory.java b/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetFactory.java index 19eae68a5..05fa042c0 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetFactory.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 2.0, as published by the @@ -43,7 +43,6 @@ import com.mysql.cj.protocol.ResultsetRows; import com.mysql.cj.protocol.a.NativePacketPayload; import com.mysql.cj.protocol.a.result.OkPacket; -import com.mysql.cj.protocol.a.result.ResultsetRowsCursor; public class ResultSetFactory implements ProtocolEntityFactory { @@ -138,9 +137,10 @@ public ResultSetImpl createFromResultsetRows(int resultSetConcurrency, int resul rs.setResultSetType(resultSetType); rs.setResultSetConcurrency(resultSetConcurrency); - if (rows instanceof ResultsetRowsCursor && st != null) { + if (st != null) { rs.setFetchSize(st.getFetchSize()); } + return rs; } diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetImpl.java b/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetImpl.java index 1f24099d3..40b0011fa 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetImpl.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetImpl.java @@ -1984,7 +1984,7 @@ public void setFetchDirection(int direction) throws SQLException { @Override public void setFetchSize(int rows) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { - if (rows < 0) { /* || rows > getMaxRows() */ + if (rows < 0 && rows != Integer.MIN_VALUE) { /* || rows > getMaxRows() */ throw SQLError.createSQLException(Messages.getString("ResultSet.Value_must_be_between_0_and_getMaxRows()_66"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } diff --git a/src/test/java/testsuite/regression/ResultSetRegressionTest.java b/src/test/java/testsuite/regression/ResultSetRegressionTest.java index 628e2e577..0d4757db9 100644 --- a/src/test/java/testsuite/regression/ResultSetRegressionTest.java +++ b/src/test/java/testsuite/regression/ResultSetRegressionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 2.0, as published by the @@ -8200,4 +8200,51 @@ void testBug107215() throws Exception { } } + /** + * Tests fix for Bug#113129 (Bug#36043145), setting the FetchSize on a Statement object does not affect. + * + * @throws Exception + */ + @Test + void testBug113129() throws Exception { + Statement testStmt = this.conn.createStatement(); + int fetchSizeToTest1 = 5; + int fetchSizeToTest2 = 10; + + // executeQuery returns a different ResultSet when executing a ping query, need to test it too. + testStmt.setFetchSize(fetchSizeToTest1); + this.rs = testStmt.executeQuery("/* ping */"); + assertEquals(fetchSizeToTest1, this.rs.getFetchSize()); + this.rs.setFetchSize(fetchSizeToTest2); + assertEquals(fetchSizeToTest2, this.rs.getFetchSize()); + + // Static rows. + testStmt.setFetchSize(fetchSizeToTest1); + this.rs = testStmt.executeQuery("SELECT 1"); + assertEquals(fetchSizeToTest1, this.rs.getFetchSize()); + this.rs.setFetchSize(fetchSizeToTest2); + assertEquals(fetchSizeToTest2, this.rs.getFetchSize()); + this.rs.next(); + + // Dynamic fetch. + testStmt.setFetchSize(Integer.MIN_VALUE); + this.rs = testStmt.executeQuery("SELECT 1"); + this.rs.next(); + assertEquals(Integer.MIN_VALUE, this.rs.getFetchSize()); + this.rs.setFetchSize(fetchSizeToTest2); + assertEquals(fetchSizeToTest2, this.rs.getFetchSize()); + + // Cursor based. + Properties props = new Properties(); + props.setProperty(PropertyKey.useCursorFetch.getKeyName(), "True"); + Connection cursorConn = getConnectionWithProps(props); + testStmt = cursorConn.createStatement(); + testStmt.setFetchSize(fetchSizeToTest1); + this.rs = testStmt.executeQuery("SELECT 1"); + assertEquals(fetchSizeToTest1, this.rs.getFetchSize()); + this.rs.setFetchSize(fetchSizeToTest2); + assertEquals(fetchSizeToTest2, this.rs.getFetchSize()); + this.rs.next(); + } + }