pgjdbc: Setting the fetch size on a CallableStatement does not work.
Setting the fetch size on a CallableStatement does not work, when reading the resultset the default fetch size is used. If the default fetch size (that can be configured with the driver property ‘defaultRowFetchSize’) is left to its default value 0 (load the entire resultset), for CallableStatements, regardless of the fetch size set on the statement the entire resultset is loaded in memory. A heap dump analysis tool can also reveal this.
Driver Version: 9.4.1211
Java Version: 11
OS Version: Windows 10
PostgreSQL Version:9.6
To Reproduce Steps to reproduce the behaviour:
Assuming the following stored function exists on the database:
CREATE OR REPLACE FUNCTION GetCostCenters() RETURNS REFCURSOR AS $$
DECLARE
cl1 REFCURSOR;
BEGIN
OPEN cl1 FOR
-- any select returning 20 rows for example
select CostCenterName, CostCenterNo from CostCenter;
RETURN cl1;
END;
$$ LANGUAGE plpgsql;
See the following code snippet, nothing is closed to keep things simple:
Connection conn = ....; // get a Connection
CallableStatement cs = conn.prepareCall("{? = call getCostCenters()}");
cs.registerOutParameter(1, Types.REF_CURSOR);
cs.setFetchSize(10);
cs.execute();
ResultSet rs = (ResultSet) cs.getObject(1);
System.out.println("RS fetch size: " + rs.getFetchSize() + ", should be " + cs.getFetchSize());
System.out.println("Checking what is already loaded in the RS ...");
// using Spring Framework ReflectionTestUtils to peek into the rows member of the PgResultSet
List<byte[][]> rows = (List<byte[][]>) ReflectionTestUtils.getField(rs, "rows");
System.out.println(rows.size() + " records already loaded.");
Expected behaviour: The fetch size set on the CallableStatement should be used when processing the resultset resulted from the CallableStatement.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 15 (7 by maintainers)
Ok, I confirmed that this is really an issue, fixing it is not a trivial task. I will look into it